1.开启EnableAspectJAutoProxy注解
@EnableAspectJAutoProxy注解【相当于加了个BeanPostProcessor】,会导入AspectJAutoProxyReqistrar这个类,会把AnnotationAwareAspectJAutoProxyCreator注册进spring容器中,注册进容器后还会看这两个属性的值【proxyTargetClass,exposeProxy】基于BeanDefinition技术给这两个属性赋值,也就是实例化创建完对象后有个BeanDefinition后置处理【getPropertiseValue().add() 。proxyTargetClass属性决定了Spring AOP使用JDK动态代理还是CGLIB来创建代理对象。true就是用CGLIB exposeProxy为true就是能从【AopCOntext.currentProxy( )】ThreadLocal里拿到代理对象】
当执行到初始化后的方法时候,会遍历所有的BeanPostProcessor,然后就执行到AnnotationAwareAspectJAutoProxyCreator他父类的这个方法,然后会基于bean去创建代理对象【这里是UserService为例】。
2.基于bean创建代理对象
1.首先会判断是不是AOP的基础设施类,如果bean是这些类型就无需Aop【包括Aspect切面bean Advisor类 Advice类等等】,然后把bean名字放入map,value为false无需Aop做个缓存,这里也可以自定义扩展哪些bean不用进行Aop,无需Aop直接返回普通对象。
如何找的Advisor?
先去找所有的Advisor【通过bean工厂找到所有显式定义的Advisor类型的bean 支持Order注解排序 放入list】然后还会找到@Aspect切面【遍历所有bean 看哪个类上有@Aspect注解 】里的所有没有加@PointCut注解的方法,然后按照通知的指定顺序和方法名字进行排序,接下来把方法就封装成Advisor,最后加入list,这时list就是最完整的了。然后对总的list进行筛选【类匹配器,方法匹配器(这里面应该有3次匹配)】和排序,最后返回的就是符合条件的所有Advisor。
切面方法的Advisor是怎么生成的?
会先拿到注解上写的PointCut,如果没有写那这个方法就被过滤掉了,还有另一种写法不会被过滤。
然后过滤完返回的就是Advisor对象了。
如果最后有匹配上的ProxyFactory就会去创建代理对象了
3.ProxyFactory创建代理对象
JDK或者CGLIB调用对应的方法
前情提要:
ProxyFactory在生成代理对象之前,也就是最后一步才需要决定到底是使用JDK动态代理还是CGLIB技术【最后调用createProxy().getProxy()方法的时候 】去生成代理对象
4.得到代理对象后调用代理对象的方法
JDK
JDK产生的代理对象最后再执行某个方法的时候都会进到invoke方法里来
invoke方法详解
代理对象在执行某个方法的时候:
1.首先取出TargetSource,然后判断当前执行的方法是什么,如果是equals,hashCode这些就不走代理逻辑,就直接执行被代理的方法。如果exposeProxy设置为true会把代理对象放到TheardLocal里面去,然后调用TargetSource的getTarget方法 取出真正的被代理对象【这部分也可以自己实现】
2.然后筛选匹配的Advisor然后去执行【遍历所有的Advisor 然后通过Pointcut筛选 类匹