Spring5深入浅出篇:基于注解实现的AOP
基于注解的AOP编程的开发步骤
- 原始对象
- 额外功能
- 切⼊点
- 组装切⾯
可以发现其实1,2,3最终目的就是为了去组装切面,其实这里和我们传统开发aop的步骤是一样的
# 通过切⾯类 定义了 额外功能 @Around 定义了 切⼊点 @Around("execution(* login(..))") @Aspect 切⾯类 package com.baizhiedu.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; /* 传统使用配置文件开发aop步骤 1. 额外功能 public class MyArround implements MethodInterceptor{ public Object invoke(MethodInvocation invocation){ Object ret = invocation.proceed(); return ret; } } 2. 切⼊点 <aop:config <aop:pointcut id="" expression="execution(*login(..))"/> */ @Aspect public class MyAspect { //这里通过注解的方式定义切入点表达式 @Around("execution(* login(..))") public Object arround(ProceedingJoinPoint joinPoint) throws Throwable { //增强额外方法,这里还是通过日志的形式表现 System.out.println("----aspect log ------"); //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint Object ret = joinPoint.proceed(); return ret; } }
<bean id="userService" class="com.baizhiedu.aspect.UserServiceImpl"/> <!-- 切⾯ 1. 额外功能 2. 切⼊点 3. 组装切⾯ --> <bean id="arround" class="com.baizhiedu.aspect.MyAspect"/> <!--告知Spring基于注解进⾏AOP编程--> <aop:aspectj-autoproxy />
细节
切⼊点复⽤
首先第一个问题,为什么需要切入点复用呢?主要是为了在同一个切入点增加一个额外方法,比如我们给切入点添加了日志方法还需要添加事务相关方法时,就需要重复编码导致代码可维护性差
首先看如下代码
@Aspect public class MyAspect { //这里通过注解的方式定义切入点表达式 @Around("execution(* login(..))") public Object arround(ProceedingJoinPoint joinPoint) throws Throwable { //增强额外方法,这里还是通过日志的形式表现 System.out.println("----aspect log ------"); //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint Object ret = joinPoint.proceed(); return ret; } //可以明显发现这里写了重复的代码,如果我们需要将login方法替换成register方法将会需要修改每一个 @Around("execution(* login(..))") public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable { //增强额外方法,这里还是通过日志的形式表现 System.out.println("----事务相关操作 ------"); //这里不再通过MethodInvocation的方式来代表原始方法执行,而是ProceedingJoinPoint Object ret = joinPoint.proceed(); return ret; } }
通过切入点注解 @Pointcut 进行优化
切⼊点复⽤:在切⾯类中定义⼀个函数 上⾯@Pointcut注解 通过这种⽅式,定义切 ⼊点表达式,后续更加有利于切⼊点复⽤。 @Aspect public class MyAspect { @Pointcut("execution(* login(..))") public void myPointcut(){} @Around(value="myPointcut()") public Object arround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("----aspect log ------"); Object ret = joinPoint.proceed(); return ret; } @Around(value="myPointcut()") public Object arround1(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("----aspect tx ------"); Object ret = joinPoint.proceed(); return ret; } }
动态代理的创建⽅式
AOP底层实现 2种代理创建⽅式 1. JDK 通过实现接⼝ 做新的实现类⽅式 创建代理对象 2. Cglib通过继承⽗类 做新的⼦类 创建代理对象 默认情况 AOP编程 底层应⽤JDK动态代理创建⽅式 如果切换Cglib 1. 基于注解AOP开发 <aop:aspectj-autoproxy proxy-target-class="true" /> 2. 传统的AOP开发 <aop:config proxy-target-class="true"> </aop>
AOP阶段知识总结
以上便是本文的全部内容,我是全干程序员demo,每天为你带来最新好用的开发运维工具,如果你觉得用,请点赞,让更多的人了解相关工具
如果你想了解更多关于全干程序员demo,还有更多付费工具免费破解,可以关注公众号-全干程序员demo,后面文章会首先同步至公众号