这篇文章主要介绍了Spring AOP AspectJ使用及配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
AspectJ是一个基于Java语言的AOP框架,Spring2.0以后新增了对AspectJ切点表达式支持。因为Spring1.0的时候Aspectj还未出现;
AspectJ1.5中新增了对注解的支持,允许直接在Bean类中定义切面。新版本的Spring框架建
议我们都使用AspectJ方式来开发AOP,并提供了非常灵活且强大的切点表达式 ;
当然无论使用Spring自己的AOP还是AspectJ相关的概念都是相同的;
注解配置
依赖导入:
通知类型
- @AspectJ提供的通知类型:
- @Before 前置通知 在原始方法执行前执行
- @AfterReturning 后置通知 在原始方法执行前执行
- @Around 环绕通知 彻底拦截原始方法的执行,执行前后都可以增加逻辑,也可以不执行原始方法
- @AfterThrowing抛出通知,执行原始方法出现异常时执行
- @After 最终final通知,不管是否异常,原始方法调用后都会执行
- @DeclareParents 引介通知,相当于IntroductionInterceptor (了解即可)
定义切点
通过execution函数来定义切点
语法:execution(访问修饰符 返回类型 方法名 参数 异常)
表达式示例:
- 匹配所有类public方法:execution(public * *(..))第一个*表示返回值 ..表示任意个任意类型参数
- 匹配指定包下所有方法: execution(* cn.xxx.dao.*(..)) 第一个想*表示忽略权限和返回值类型
- 匹配指定包下所有方法:execution(* cn.xxx.dao..*(..))包含子包
- 匹配指定类所有方法: execution(* cn.xxx.service.UserService.*(..))
- 匹配实现特定接口所有类方法 : execution(* cn.xxx.dao.GenericDAO+.*(..))
- 匹配所有save开头的方法: execution(* save*(..))
前置通知
pom依赖:
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.2.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.2.RELEASE</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-test --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.2.2.RELEASE</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> </dependencies></project>xml需要添加aop名称空间及xsd:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://.yh.demo2.XMLAdvice2"/>通知类:
import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.JoinPoint;public class XMLAdvice { public void before(JoinPoint pointcut){ System.out.println("前置通知 切点:"+pointcut); } public void afterReturning(JoinPoint point,Object result){ System.out.println("后置通知 切点:"+point); } public void after(JoinPoint point){ System.out.println("最终通知 切点:"+point); } public void exception(JoinPoint point,Throwable e){ System.out.println("异常通知: " + e+"切点:"+point); } public void around(ProceedingJoinPoint point) throws Throwable { System.out.println("环绕前"); point.proceed(); System.out.println("环绕后"); }}你会发现 ,无论是XML还是注解都不需要手动指定代理,以及目标对象,Aspectj会从切点中获取目标对象信息并自动创建代理;
AspectJ是目前更流行的方式,具体采用XML还是注解需要根据项目具体情况,小组协作开发推荐xml;
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。