目录
AspectJ框架
【Spring|浅谈AspectJ框架】AspectJ常见通知类型
AspectJ 的切入点表达式(掌握)
AspectJ的前置通知@Before
前置方式通知注释的实现
前置通知方式参数jionpoint解析
AspectJ框架切换JDK动态代理和CGLib动态代理
AspectJ框架
文章图片
AspectJ 是一个面向切面的框架,他定义了 AOP 的一些语法,有一个专门的字节码生成器来生成遵守 java 规范的 class 文件。
文章图片
AspectJ 的通知类型不仅包括我们之前了解过的四种通知:前置通知、后置通知、环绕通知和异常通知,而且还多出一种最终通知即无论程序是否正常执行,最终通知的代码会得到执行。
原因就是切入点表达式,切入点表达式可以标识切面织入到哪些类的那些方法当中,就不需要像我们之前利用 spring 实现 AOP 那样各种配置。只要把切面的实现配置好了,再把这个切入点表达式写好就可以了。
AspectJ常见通知类型
AspectJ 中常用的通知有四种类型:
文章图片
文章图片
文章图片
文章图片
1)前置通知@Before
2)后置通知@AfterReturning
3)环绕通知@Around
4)最终通知@After
5)定义切入点@Pointcut(了解)
AspectJ 的切入点表达式(掌握)
规范的公式:
execution(访问权限 方法返回值 方法声明(参数) 异常类型)
简化后的公式:
execution( 方法返回值 方法声明(参数) )
用到的符号:示例:
*代码任意个任意的字符(通配符)
..如果出现在方法的参数中,则代表任意参数
如果出现在路径中,则代表本路径及其所有的子路径
execution(public * *(..)) :任意的公共方法
execution(* set*(..)):任何一个以“set”开始的方法
execution(* com.xyz.service.impl.*.*(..)):任意的返回值类型,在com.xyz.service.impl包下的任意类的任意方法的任意参数
execution(* com.xyz.service..*.*(..)):任意的返回值类型 ,在com.xyz.service及其子包下的任意类的任意方法的任意参数
com.xyz.service.a.b.*.*(..)com.xyz.service.*.*(..)
execution(* *..service.*.*(..)):service之前可以有任意的子包
execution(* *.service.*.*(..)):service之前只有一个包
AspectJ的前置通知@Before
在目标方法执行前切入切面功能.在切面方法中不可以获得目标方法的返回值,只能得到目标方法的签名。
实现的步骤:
添加依赖
spring-aspects
1)创建业务接口
2)创建业务实现
3)创建切面类,实现切面方法
4)在applicationContext.xml文件中进行切面绑定
文章图片
项目案例:
@Aspect//交给AspectJ的框架去识别切面类
@Component
public class MyAspect {
/**
* 所有切面的功能都是由切面方法来实现的
* 可以将各种切面都在此类中进行开发
*
* 前置通知的切面方法的规范
* 1)访问权限是public
* 2)方法的返回值是void
* 3)方法名称自定义
* 4)方法没有参数,如果有也只能是JoinPoint类型
* 5)必须使用@Before注解来声明切入的时机是前切功能和切入点
*参数:value指定切入点表达式
*
* 业务方法
* public String doSome(String name, int age)
*/
@Before(value = "https://www.it610.com/article/execution(public String com.bjpowernode.s01.SomeServiceImpl.*(String,int))")
public void myBefore(){
System.out.println("切面方法中的前置通知功能实现............");
}
@Before(value = "https://www.it610.com/article/execution(public * com.bjpowernode.s01.SomeServiceImpl.*(..))")
public void myBefore(){
System.out.println("切面方法中的前置通知功能实现............");
}
@Before(value = "https://www.it610.com/article/execution( * com.bjpowernode.s01.*.*(..))")
public void myBefore(JoinPoint jp){
System.out.println("切面方法中的前置通知功能实现............");
System.out.println("目标方法的签名:"+jp.getSignature());
System.out.println("目标方法的参数:"+ Arrays.toString(jp.getArgs()));
}
@Before(value = "https://www.it610.com/article/execution( * com.bjpowernode.s01..*(..))")
public void myBefore(){
System.out.println("切面方法中的前置通知功能实现............");
}
@Before(value = "https://www.it610.com/article/execution( * *(..))")
public void myBefore(){
System.out.println("切面方法中的前置通知功能实现............");
}
}
前置方式通知注释的实现
文章图片
文章图片
文章图片
前置通知方式参数jionpoint解析
文章图片
AspectJ框架切换JDK动态代理和CGLib动态代理
文章图片
===>默认是JDK动态代理,取时必须使用接口类型
==>设置为CGLib子类代理,可以使用接口和实现类接
记住:使用接口来接,永远不出错。
推荐阅读
- 单元测试|如何写Java单元测试
- 面试官(什么是脚手架(为什么需要脚手架?常用的脚手架有哪些?))
- spring|架构设计之Spring-Session的分布式集群会话管理
- #|【Springboot】微服务中使用腾讯云T-Sec天御对文本及图片内容进行安全检测
- #|【SpringBoot】微服务中异步调用数据提交数据库的问题
- java|java8函数式编程--- 代码重构,抽出方法
- java|java 重构函数_包会,教你用Java函数式编程重构烂代码
- Spring|面试问题(Spring中Bean 的生命周期)
- Spring系列|Spring系列六(AOP概念和使用)