Spring框架学习—Spring AOP纯xml模式
spring中AOP的代理选择
- Spring 实现AOP思想使⽤的是动态代理技术
- 默认情况下,Spring会根据被代理对象是否实现接⼝来选择使⽤JDK还是CGLIB。当被代理对象没有实现任何接⼝时,Spring会选择CGLIB。当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术,不过我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。
spring中AOP的实现
Spring是模块化开发的框架,使⽤aop就引⼊aop的jar
- 引入
jar
包
<!--spring aop的jar包支持-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.1.12.RELEASE</version>
</dependency>
<!--第三方的aop框架aspectj的jar-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
XML配置
-
进行
aop
相关的xml
配置,配置aop
的过程其实就是把aop
相关术语落地 -
使用
config
标签表明开始aop
配置,在内部配置切面aspect
,切面(aspect)
可以设置多个 -
aspect
= 切入点(锁定方法) + 方位点(锁定方法中的特殊时机)+ 横切逻辑<!--横切逻辑bean,横切逻辑就是代码,代码要写在类上,类要定义成一个bean才能融入到spring框架中--> <bean id="logUtils" class="com.lagou.edu.utils.LogUtils"></bean> <aop:config> <!--aspect = 切入点(锁定方法) + 方位点(锁定方法中的特殊时机)+ 横切逻辑--> <aop:aspect id="logAspect" ref="logUtils"> <!--切入点锁定我们感兴趣的方法,使用aspectj语法表达式,可以定义多个切入点,execution 锁定感兴趣的方法--> <aop:pointcut id="pt1" expression="execution(* *..*.*(..))"/> <aop:pointcut id="pt1" expression="execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/> <!-- 方位信息,pointcut-ref关联切入点--> <!-- aop:before前置通知/增强 method是执行的方法 pointcut-ref:关联切入点的属性 --> <aop:before method="beforeMethod" pointcut-ref="pt1"/> <!--aop:after,最终通知,无论如何都执行--> <!--aop:after-returnning,正常执行通知--> <!--returnning表示形参,告诉框架这个形参是用来接收返回值的--> <aop:after-returning method="successMethod" returning="retValue"/> <!--aop:after-throwing,异常通知--> </aop:config>
将上述部分的XML配置转换成注解模式
-
这部分在
LogUtils
类上加@Component
注解<bean id="logUtils" class="com.lagou.edu.utils.LogUtils"></bean>
-
这段代码可以在
LogUtils
类上添加注解@Aspect
<aop:aspect id="logAspect" ref="logUtils">
-
这段代码可以在
LogUtils
类上添加一个空的实现方法,并且在方法上架一个注解@Pointcut
注解的值是express的值<aop:pointcut id="pt1" expression="execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))"/>
@Pointcut("execution(* com.lagou.edu.service.impl.TransferServiceImpl.*(..))") public void pt1(){ }
-
前置通知,在方法上添加注解
@Before( )
,括号里面写切入点的方法名@Before("pt1()") public void beforeMethod(JoinPoint joinPoint) { Object[] args = joinPoint.getArgs(); for (int i = 0; i < args.length; i++) { Object arg = args[i]; System.out.println(arg); } System.out.println("业务逻辑开始执行之前执行......."); }
-
业务结束时通知注解
@After( 切入点方法名 )
-
异常时执行通知注解
@AfterThrowing( 切入点方法名 )
-
业务逻辑正常执行通知注解
@AfterReturn( value = "pt1()",returning = "retVal" )
,value
:切入点方法,returning
:返回值类型 -
环绕通知注解
@Around("pt1()")
,和上面的通知注解不要通用
-
由于AOP的这些xml的配置都变成了注解,所以要在
xml文件中加一句注解驱动的配置
<!--开启aop注解驱动 ,属性 proxy-target-class:true强制使用cglib代理 --> <aop:aspectj-autoproxy/>
-
@EnableAspectJAutoProxy
纯注解开启AOP注解驱动