SpringAOP机制 启动配置开启代理需要在配置上加EnableAspectJAutoProxy 这个注解它里面有一个Import会导入AspectJAutoProxyRegistrar。这个Import解析的地方就是在ComponentScan解析完了之后。Import导入的类有3种ImportSelector按条件批量导入。会实例化这个Selector然后调用selectImports方法返回一个要导入的类的列表最后一起调用processImport批量导入。实现ImportBeanDefinitionRegistrar接口的用于开发者自定义注册Bean。会将其实例化然后添加到缓存importBeanDefinitionRegistrars中。这里的实例化用其构造方法实例化然后处理它的Aware不会自动依赖注入。普通的将导入的类解析出来然后递归调用doProcessConfigurationClass。这时他就不是Import了而是一个普通的配置类就按流程处理就可以了。AspectJAutoProxyRegistrar属于第二种在BFPP解析的时候会将其实例化然后放入缓存中。ConfigurationClass这个类在解析的过程经常出现。它其实是配置类信息的抽象。它有配置类上注解信息AnnotationMetadata、beanName、beanMethod这些都是后面要用到的。配置类的那些注解Component、ComponentScan、Bean、Import解析过后都会设置到它里面。在BFPP的parse方法结束后会用处理配置类的reader调用它的loadBeanDefinitions方法。前面parse方法解析过后所有的配置类会变成ConfigurationClass并放到缓存中。loadBeanDefinitions会做下面这些事情处理普通Import包装成BD然后注册进容器处理Bean注解的注册方法会在BD中设置factorymethod等属性处理ImportResource这时会引入外部xml进行注册bean已经不怎么用了处理是Import的、并且实现ImportBeanDefinitionRegistrar接口的。在这个方法中会调用ImportBeanDefinitionRegistra的registerBeanDefinitions方法。那AspectJAutoProxyRegistrar内部定义的方法也就是在这里执行了。AspectJAutoProxyRegistrar的registerBeanDefinitions中会向容器中注册一个关键Bean——AnnotationAwareAspectJAutoProxyCreatorBPP。并且检查两个变量proxyTargetClass是否用cglib代理。spring默认是jdk代理exposeProxy是否暴露代理类。在调用方法时是否将代理类放到当前线程的ThreadLocal中默认是不放的至此启动类上的注解就算解析完成了。分析了这么多其实就做了一件事把AnnotationAwareAspectJAutoProxyCreator这个BPP类通过自定义的方法注册进容器了。AAAPC的生效时机在createBean方法中在doCreateBean方法之前会调用resolveBeforeInstantiation方法。这是在实例化之前对BD做处理一个点。AAAPC在这里会调用它的postProcessBeforeInstantiation和postProcessAfterInitialization方法。实例化之前的处理注意AAAPC本身没有实现这两个方法而它的父类AbstractAutoProxyCreator实现了。这里实际上执行的是父类的方法。这个方法中有一个特别隐藏的方法shouldSkip看着不起眼实际上在这里已经会创建好各种Advisor了。shouldSkip中会判断当前这个Bean是否属于切面的基础类比如AspectJPointcutAdvisor这种是的话就要跳过还会校验当前Bean是否就是Aspect注解的那个切面类这种也会跳过。在它里面调用findCandidateAdvisors方法这个方法会构建所有的Advisor并放入缓存。实际上切面构建在这里就已经完成了。findCandidateAdvisors中有两个方法findCandidateAdvisors和buildAspectJAdvisors。前者用于找实现Advisor接口的类传统SpringAop实现后者是在有Aspect注解的类。buildAspectJAdvisors流程首先会拿到BF中所有的beanName然后遍历如果类上有Aspect注解则说明它是配置类需要处理。会调用getAdvisor方法创建Advisor。对于切面中定义的每个增强方法都会创建一个Advisor类。里面会有关于增强方法的各种信息。包括pointcut、增强方法名、参数等等shouldskip执行完了所有的Advisor也是都被解析好放入缓存了。在initializeBean方法中它的流程是这样的其中第2步和第4步就会用到。其中第2步是直接返回了什么也没做1. invokeAwareMethods2. 调用BPP的postProcessBeforeInitialization3. invokeInitMethods4. 调用BPP的postProcessAfterInitialization那postProcessAfterInitialization做了什么AbstractAutoProxyCreator会在这里调用wrapIfNecessary方法这个方法就是判断是否要为当前类生成代理对象是的话就创建代理对象。首先它会调用getAdvicesAndAdvisorsForBean这个会对所有Advisor进行筛选留下可以用于增强当前bean的。判断就是看当前类中的方法是否满足切入点表达式只有有一个满足就说明需要被代理调用createProxy创建出代理类来。它会判断要用jdk还是cglib主要根据当前类实现接口的情况。判断好了之后如果是jdk就创建一个工具JdkDynamicAopProxy如果是cglib就创建ObjenesisCglibAopProxy。它们是用来创建代理类的。CglibAopProxy是如何创建代理类的判断类名有无$$,有的话说明它已经是个代理类了。这时会拿它的父类作为目标类因为cglib是通过继承来实现的。创建Enhancer就是cglib增强器。然后给它设置原始目标类、要实现的接口、代理类的命名策略代理类名通常是YourClass$$EnhancerBySpringCGLIB$$xxxx这个有时在堆栈是有出现的。创建Callback数组也就是一个个拦截器设置CallbackFilter 当代理对象的方法被调用时需要通过filter知道要选择哪个拦截器调用createProxyClassAndInstance创建代理类。至此代理类就创建完成了。主要就是Callback。至此wrapIfNecessary方法也执行完成了。postProcessAfterInitialization执行完了之后原始对象就已经被替换成了代理对象了。之后调用原始方法就会进入到代理对象的拦截器中的方法。