Spring之前和同学们详细聊过IOC循环依赖问题,接下来给同学们讲讲另外一个模块,就是AOP,也是一道面试题官方更愿意询问的模块点。什么是AOP?AOP通常称为面向切面编程(Aspect-orientedProgramming,简称AOP),是一种编程范式,是一种通过预编译方法和运行时动态代理实现程序功能统一维护的技术。通常用来隔离不同的业务逻辑,比如常见的事务管理、日志管理等。同时,AOP的实现方式有两种:cglib和jdk。为什么我们需要AOP?假设有几个实现方法需要做日志处理。通常情况下,我们只需要手动添加日志即可。我们都知道,在真实的业务代码中,代码行数和方法数是一个天文数字。手动添加工作负载是不现实的。本着程序员思考如何偷懒的习惯,我们应该想办法提高效率。因此,AOP诞生了。AOP说白了就是通过一定的匹配规则来匹配方法,然后加上相应的日志处理。AOP本身的实现是通过ASM字节码框架的动态生成技术实现的。程序运行时,根据需求(添加文件)动态创建字节码文件,这在前面提到的设计模式中的动态代理模式中也有提到。你可以再复习一遍。Aspect,AOP的核心概念:类似于Java中的类声明,在应用中常用于配置事务或日志管理。一般使用@Aspect注解或者定义一个aspect。JoinPoint:程序执行中的一个特定的点,比如方法执行,处理异常等。Pointcut:一个规则匹配的正则表达式,当有一个joinpoint可以匹配到cutpoint时,就是指定的notification关联随着变化点将被触发。忠告(Advice):切面中某个连接点所采取的动作。around(surroundingadvice)的通知方式也有5种:addbefore(pre-advice)after(post-advice)exception(异常通知)return(返回)Notification)Weaving:将aspect和目标对象联系起来创建的过程通知对象。AOP其实是一种编程思想,以上几点就是编程的具体实现规范。一个应用程序中可以有多个通知方法,因此在AOP中引入了责任链模式的设计模式。每个通知都可以通过这个模型顺序执行。当然也可以使用@Order注解。配置号越小,越早执行。关于责任链模型的大家也可以去我之前写的设计模式复习一下。AOP的执行过程之前跟大家讲IOC的时候跟大家讲过它的启动过程。同样的AOP也有指定的执行过程,但是需要IOC作为基础。IOC容器启动,用于存储对象进行对象实例化和初始化操作,将生成和完成的对象存储在容器中(容器中运行的一些对象,如BeanFactoryProcesser、methodInterceptore等,还有很多其他对象)来自容器中创建的Acquisition需要对象调用特定的方法才能开始调用。说了这么多理论知识,如果想知道里面具体的执行流程,还是老老实实,一步步调试,进入源码查看流程。首先需要准备配置一个切面@Aspect@ComponentpublicclassLogUtil{@Pointcut("execution(public*com.ao.bing.demo.spring.aop..*.*(..))")publicvoidpctMethod(){}@Around(value="pctMethod()")publicObjectaround(ProceedingJoinPointpjp)throwsThrowable{Objectret=pjp.proceed();System.out.println("Aroundadvice");returnret;}@Before("pctMethod()")publicvoidbefore(){System.out.println("Beforeadvice");}@After(value="pctMethod()")publicvoidafter(){System.out.println("Afteradvice");}@AfterReturning(value="pctMethod()")publicvoidafterReturning(){System.out.println("AfterReturningadvice");}@AfterThrowing(value="pctMethod()")publicvoidafterThrowing(){System.out.println("AfterThrowingadvice");}//主要方法测试);}}这里配置一个LogUtilsectiondemo,把5个notification都写上去,还有一个main方法,测试准备工作完成后,正式开始调试代码,首先我们在aopTestDemo中设置断点,此时,我们过去的bean对象aopTestDemo已经是一个动态代理生成的对象,里面有很多CALLBACK方法属性,什么是write方法属性呢,其实跟Spring的拦截器有关,其实是一种设计模式到说白了,观察者模式就是监听对象的行为,通知功能是通过回调机制实现的。那既然是回调方法,那就先进DynamicAdvisedInterceptor方法中privatestaticclassDynamicAdvisedInterceptorimplementsMethodInterceptor,Serializable{privatefinalAdvisedSupportadvised;publicDynamicAdvisedInterceptor(AdvisedSupportadvised){this.advised=advised;}@NullablepublicObjectintercept(Objectproxy,Methodmethod,Object[]args,MethodProxymethodProxy)throwsThrowable{ObjectoldProxy=null;booleansetProxyContext=false;Objecttarget=null;TargetSourcetargetSource=this.advised.getTargetSource();Objectvar16;try{if(this.advised.exposeProxy){oldProxy=AopContext.setCurrentProxy(proxy);setProxyContext=true;}target=targetSource.getTarget();Class>targetClass=target!=null?target.getClass():null;//从advised-key获取配置的AOP通知方法List