SpringAOP源码流程
2024-01-22 21:43:40 0 举报
Spring AOP启动和执行源码流程图
作者其他创作
大纲/内容
导入BeanDefinition注册器@Import(AspectJAutoProxyRegistrar.class)
Enhancer enhancer = createEnhancer();
代理逻辑执行invoke/intercept方法
createAopProxy()
proxyFactory.getProxy()
this.advisorFactory.getAdvisors(factory);
查找AdvisorsfindCandidateAdvisors();
设置会回调方法enhancer.setCallbacks(callbacks);
createAopProxy().getProxy(classLoader);
动态代理方式选择:cglib和jdk动态代理的自动选择getAopProxyFactory().createAopProxy(this)
根据注解类型创建advice,this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
proxyFactory.setTargetSource(targetSource);
在Bean的创建过程中,会调用AnnotationAwareAspectJAutoProxyCreator父类AbstractAutoProxyCreator的实例化前方法postProcessBeforeInstantiation进行切面类解析生成Advisor
判断beanType上是否有@AspectJ注解Class<?> beanType = this.beanFactory.getType(beanName);this.advisorFactory.isAspect(beanType)
大多数情况下会根据被代理类是否继承了接口来选择,如果继承了接口使用jdk动态代理,如果没有继承接口使用cglib代理。也可以由用户指定使用cglib动态代理,使用注解属性@EnableAspectJAutoProxy(proxyTargetClass = true)
创建代理对象createProxyClassAndInstance
在执行方被代理类的方法时会先执行DynamicAdvisedInterceptor类的intercept()方法
return advisors;
从类图可以看出该类继承了BeanPostprocessor,继承了Aware回调接口
如果当前beanClass是上面任意一个,将不会进行切面解析if (isInfrastructureClass(beanClass))
JDK 动态代理
AnnotationAwareAspectJAutoProxyCreator在生成Bean是会调用Aware回调接口设置类加载器,BeanFactory,其中在设置BeanFactory时还会创建一个关键组件aspectJAdvisorsBuilder,这个组件就是用来解析切面生成Advisor
最终执行顺序为:@Around(有用户决定是否继续往下调用)-->@Before-->被代理方法-->@AfterReturning-->@AfterThrowing(有异常时调用)-->@After
如果有的话,解析并创建AdvisorList<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
如果当前bean已经解析过了,就不用再解析了if (this.advisedBeans.containsKey(cacheKey))
@After-->@AfterThrowing-->@AfterReturning-->@Before-->@Around
invocation.proceed();
得到会对被代理逻辑方法Callback[] callbacks = getCallbacks(rootClass);
SpringAOP加上@EnableAspectJAutoProxy注解标识开AOP,在整注解上使用Import(AspectJAutoProxyRegistrar.class)导入一个代理对象创建的BeanDefinition注册器AspectJAutoProxyRegistrar,在这个注册器中会真正注册一个BeanDefinition,这个BeanDefinition就是一个BeanPostprocessor,会在Bean的实例化前进行advisor的查找,在初始化后进行AOP的动态代理
得到所有非@Pointcut标注的方法并排序,包括普通方法和加@Before等注解标注的方法getAdvisorMethods(aspectClass)
创建动态代理逻辑createProxy
执行各个MethodInterceptor,也就是@before标注的方法逻辑封装成的MethodInterceptor,在这里面会进行递归return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
倒序advisor,和执行代理逻辑有关,因为在执行代理逻辑时是递归调用,所以排在最后的advisor反而最新执行,所以这里进行了倒序eligibleAdvisors = sortAdvisors(eligibleAdvisors);
这里会注册一个实现了BeanPostprocessor的beanDefinition(AnnotationAwareAspectJAutoProxyCreator)这个就是进行Spring AOP的核心类
上面导入的类继承了ImportBeanDefinitionRegistrar接口,会调用registerBeanDefinitions()方法进行BeanDefinition注册
创建动态代理return proxyFactory.getProxy(getProxyClassLoader())
当前的执行的代理方法的位置等于所有代理逻辑的最后一个时,执行被代理类本生的方法if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); }
AnnotationAwareAspectJAutoProxyCreator
添加advisorproxyFactory.addAdvisors(advisors);
在Bean的生命周期的初始化后,会进行AOP筛选,对需要进行AOP的bean进行动态代理postProcessAfterInitialization()
已jdk动态代理的invoke方法为例cglib的逻辑与jdk一致
执行proceed方法,这里就会进行代理逻辑的递归调用retVal = invocation.proceed();
postProcessAfterInitialization
拿到解析好的所有Advisor,因为之前已经解析好了,这里会从缓存中获取List<Advisor> candidateAdvisors = findCandidateAdvisors();
@EnableAspectJAutoProxy
aspectJAdvisorsBuilder这个就是前面提到的使用Aware回调创建的,用来解析切面aspectJAdvisorsBuilder.buildAspectJAdvisors()
直接从BeanFactory中获取Advisorthis.advisorRetrievalHelper.findAdvisorBeans();
返回代理对象return proxy;
利用Spring提供的代理创建工厂进行动态代理创建ProxyFactory proxyFactory = new ProxyFactory();
postProcessBeforeInstantiation实例化前方法进行切面解析
cglib动态代理
调用AnnotationAwareAspectJAutoProxyCreator的findCandidateAdvisors();方法
0 条评论
回复 删除
下一页