1、概述
它最大的作用是什么?
在不更改源代码的情况下,对其原有功能进行增强。使得代码的重用率、开发效率、维护产生极大的方便。
运用场景
最常见的有:事务、日志、请求拦截等
2、使用
如何在Spring中使用AOP?
1、开启配置
@EnableAspectJAutoProxy
2、写代理类和被代理的类
@Component
@Aspect
public class AopConfig {
@PostConstruct
public void init(){
System.out.println();
}
@Pointcut("execution(* com.dh.aop.package1.Demo1.*(..))")
public void pointCut(){}
@Before("pointCut()")
public void before(){
System.out.println("before running... ");
}
}
@Component
public class Demo1 {
public void testAop(){
System.out.println("com.dh.aop.package1.Demo1.test1 running...");
}
}
当我们从容器中拿出Demo1调用testAop的时候,打印如下:
before running...
com.dh.aop.package1.Demo1.test1 running...
这就是现象,
3、原理
本文不讲应用,讲的是AOP在Spring实现的位置,具体实现的逻辑代码下一篇说。
首先我们看从Spring容器中拿到的Demo1的对象:
这里很明显,我们的Demo1并不是我们自己写的Demo1了,而是被代理后的Demo1,此代理为Cglib代理,且在我们的类中加入了几个变量,这个变量不是重点,是cglib做一些回调的扩展。
那么到这里我们就能知道,Spring使用Cglib对我们的原始类进行代理,那么Spring是在哪里对我们的类进行代理的呢?
首先我们要知道,Spring的执行流程如下:
这个图是Spring的执行流程,我们这里要找的方法在refresh的registerBeanPostProcessors和finishBeanFactoryInitialization方法。
registerBeanPostProcessors()
注册BeanPostProcessor后置处理器,这里的BeanPostProcessor是Spring的后置处理器,可用与我们的Bean实例化以后,对我们的Bean进行改变的类,例如下:
public class TestMyProxyBeanPostProcess implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Demo1){
/** 代理Demo1这个类 */
bean = 代理的类
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof Pojo1){
}
return bean;
}
}
这里可以直接将bean的值更改,并且return回去当做新的bean。
在我们Spring当中,AOP功能就是使用BeanPostProcessor来实现的。此BeanPostProcessor的名字为:AnnotationAwareAspectJAutoProxyCreator。
加入此后置处理器的配置其实就是因为我们的@EnableAspectJAutoProxy,此注解中拥有一个@Import(AspectJAutoProxyRegistrar.class)注解,此AspectJAutoProxyRegistrar中执行回调时有一行代码AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);就是加入此后置处理器的。
finishBeanFactoryInitialization()
我们Spring当中所有的单例Bean都是在此方法中进行初始化的(我们这里不讲Bean初始化,只讲AOP的实现位置),我们定位代码到:
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
可以看到我们的Demo1已经实例化出来了:
且此时是原始的对象,并没有实例化,那么我们再往下面走:
注意看,此initializeBean方法执行完的返回值Object就是Demo1的代理类,且为Cglib代理,那么就说明实现AOP代理的方法就这个org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)方法,进入这个方法看看:
注意此时bean还是原始对象,而不是代理对象,我们F6走下一步后:
我们的bean变成了代理对象,那么说明重要的代码就在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法当中去:
这里要遍历getBeanPostProcessor拿到的BeanPostProcessor的postProcessAfterInitialization方法,并将返回值赋值给当前的bean,相当于是更改了Bean。我们来看看getBeanPostProcessor这个方法的返回值有哪些BeanPostProcessor:
我们看这里的这个第3个元素的PostProcessor,此就是我们前面@EnableAspectJAutoProxy注解加入的BeanPostProcessor,我们进入这个循环,看看当这个Processor执行完后是否bean就变成了代理对象。
当前是循环到我们的AnnotationAwareAspectJAutoProxyCreator了,且当前bean仍然是原始类,现在我们F6走一步:
看我们的Bean已经变成了代理类,那么我们这里就明白了实现代理AOP的位置了,下面我们简单的看看AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization方法,看看它咋做的。
更重点的就是org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization此方法的wrapIfNecessary方法:
这个方法的代码里面怎么实现的AOP,我们下次再聊