目录
AOP的作用:
当一批代码都要实现某一功能时,通过aop(动态代理方式),在代理上添加,删除功能
在不修改源代码的情况下
- 权限校验
- 日志记录
- 性能监控
- 事务控制.
底层实现原理
动态代理
- java动态代理:用于实现了接口的类产生代理
- Cglib代理:用于没有实现接口的类产生代理对象,生成子类对象
Spring 的基于 AspectJ 的 AOP 开发
- spring的aop(弃用)
- AspectJ的aop(spring觉得好用,就引入进来)
AOP相关术语
- Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只 支持方法类型的连接点.
- Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义.
- Advice(通知/增强):所谓通知是要添加的方法。通知分为前置通知,后置 通知,异常通知,最终通知,环绕通知(切面要完成的功能)
- Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类 动态地添加一些方法或 Field. Target(目标对象):代理的目标对象
- Weaving(织入):是将增加的方法应用到UserDao的save方法的过程。spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装在期织入
- Proxy(代理):一个类被 AOP 织入增强后,就产生一个结果代理类
- Aspect(切面): 是切入点和通知/引介的结合
AOP的入门开发
编写目标类并配置
编写切面类(增强的方法)并配置
public class MyAspectXml { public void before(JoinPoint joinpoint) { System.out.println("前置增强" + joinpoint); } public void afterruning(Object result) { System.out.println("后置增强" + result); } public void after(JoinPoint joinPoint) { System.out.println("最终增强" + joinPoint); } public Object around(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("还绕前"); Object object = joinPoint.proceed();//原本的方法 System.out.println("还绕后"); return object; } public void afterThrowing(Throwable ec) { System.out.println("异常抛出通知" + ec.getMessage()); } }
AOP的配置
<!--配置增强对象--> <bean id="produtodao" class="com.spring.aop.ProdutoDapimpl"></bean> <!--配置切面类--> <bean id="aspectxml" class="com.spring.aop.MyAspectXml"></bean> <!--aop配置--> <aop:config> <!--配置切入点,哪些方法需要增强--> <aop:pointcut id="pointcut1" expression="execution(* com.spring.aop.ProdutoDapimpl.save(..))"/> <aop:pointcut id="pointcut2" expression="execution(* com.spring.aop.ProdutoDapimpl.delete(..))"/> <aop:pointcut id="pointcut3" expression="execution(* com.spring.aop.ProdutoDapimpl.update(..))"/> <aop:pointcut id="pointcut4" expression="execution(* com.spring.aop.ProdutoDapimpl.find(..))"/> <!--配置切面,增强的什么方法--> <aop:aspect ref="aspectxml"> <!--前置通知 method增强的方法--> <aop:before method="before" pointcut-ref="pointcut1"/> <!--后置通知--> <aop:after-returning method="afterruning" pointcut-ref="pointcut1" returning="result"/> <!--最终通知,无论有没有异常,都会执行--> <aop:after method="after" pointcut-ref="pointcut2"/> <!--环绕通知--> <aop:around method="around" pointcut-ref="pointcut3"/> <!--异常抛出通知--> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut4" throwing="ec"/> </aop:aspect> </aop:config>