Spring Aop代理对象创建和代理方法执行流程
2022-07-11 16:09:35 12 举报
Spring Aop代理对象创建和代理方法执行流程
作者其他创作
大纲/内容
否
BeanFactoryUtils.beanNamesForTypeIncludingAncestors获取容器中所有的beanName
是
AOP对象注解创建过程
XXXAdvice
applyBeanPostProcessorsBeforeInstantiation遍历容器中所有的BPP
false
proxyFactory.getProxy(getProxyClassLoader())真正的创建代理对象
invocation.set(oldInvocation)将老的MethodInvocation放到ThreadLocal中
基础设施类有:PointCut、Advice、Advisor
AOP方法执行过程
ExposeInvocationInterceptor#invoke
判断方法是否符合pointCut的表达式
new InstantiationModelAwarePointcutAdvisorImpl()该类继承自Advisor
CglibAopProxy.CglibMethodInvocation#proceed ->ReflectiveMethodInvocation#proceed
创建代理工厂 ProxyFactory proxyFactory = new ProxyFactory(); // 获取当前类中相关属性 proxyFactory.copyFrom(this);
所有红色的线表示执行返回走的路线,优先级低于黑线
loadBeanDefintionsxml解析
org.springframework.aop.aspectj.AspectJPointcutAdvisor#0org.springframework.aop.aspectj.AspectJPointcutAdvisor#1org.springframework.aop.aspectj.AspectJPointcutAdvisor#2org.springframework.aop.aspectj.AspectJPointcutAdvisor#3org.springframework.aop.aspectj.AspectJPointcutAdvisor#4
parseAdvice解析advice节点并注册到bean工厂中
advisors是否为空
JoinPointMatch jpm = getJoinPointMatch(pmi)获取JoinPoint匹配器
生成的对象会被放到BeanDefintion集合中
AfterReturningAdviceInterceptor#invoke
initializeBeanbean初始化
this.advisorFactory.isAspect(beanType)判断当前类是否被@Aspect修饰
registerBeanPostProcessors
adviceDefinition.getConstructorArgumentValues()设置构造函数的参数,后面就会用构造函数来创建bean
AspectJAwareAdvisorAutoProxyCreatorCommonAnnotationBeanPostProcessorAutowiredAnnotationBeanPostProcessor.......等都属于这个类型的BPP
MethodBeforeAdviceInterceptor#invoke
ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi)获取执行的JoinPoint对象
pjp.proceed(args)Around方法中的方法调用
this.aspectJAdvisorsBuilder.buildAspectJAdvisors()注解修饰的Advisor
AbstractAutoProxyCreator#postProcessBeforeInstantiation
Xml解析方式
advice链为空并且方法为public
true
doCreateBean
findAdvisorBeans
isInfrastructureClass(beanClass) || this.aspectJAdvisorFactory.isAspect(beanClass))判断是不是一个基础设施类,并且有没有被@Aspect修饰
是否是一个原始的实例
interceptorOrInterceptionAdvice).invoke(this)普通拦截器直接调用拦截器
shouldSkip是否需要跳过生成代理
this.advisorFactory.getAdvisors(factory)
返回代理对象
Advice、Pointcut、Advisor、AopInfrastructureBean
返回原对象
这里创建的都是原型的对象
第一个就是DynamicAdvisedInterceptor,这个就是aop的拦截器类
AspectJAfterThrowingAdvice#invoke
......省略一部分bean的创建流程
这里是BeanDefintion类型
resolveValueIfNecessary
findCandidateAdvisors()获取所有的Advisor
该方法会向工厂中创建并注册AnnotationAwareAspectJAutoProxyCreator
AspectJPointCutAdvisor
mi.proceed()
beanDefinitions.add(advisorDefinition)
AspectJExpressionPointcut
invocation.set(mi)将传递过来的MethodInvocation存放到ThreadLocal中
hasInstantiationAwareBeanPostProcessors是否有这个类型的BPP
wrapIfNecessary
获取参数个数,循环创建对象
缓存生成的代理bean类型中并返回代理对象
无意义,单纯少画线
获取到构造函数
proxyFactory.addAdvisors(advisors)添加代理工厂的增强器
new RootBeanDefinition(MethodLocatingFactoryBean.class)
剩下的流程和注解的一样啦
DynamicAdvisedInterceptor#intercept
resolveConstructorArguments这里会创建构造函数需要的对象
Class<?> targetClass = (target != null ? target.getClass() : null)获取代理对象的Class对象
通过该方法来获取beanNamesForTypeIncludingAncestors
Advisor创建过程需要创建的对象
MethodInvocation oldInvocation = invocation.get()从ThreadLocal中获取老的拦截器
是否继承自InterceptorAndDynamicMethodMatcher
1.解析阶段AspectJAwareAdvisorAutoProxyCreator在解析aop-config标签时注册的BD解析aop:around对应的标签时会生成对应的Advisor ->org.springframework.aop.aspectj.AspectJPointcutAdvisor#0 ... <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 开启AOP注解功能2.创建Bean过程 1.创建第一个bean判断有没有InstantiationAwareBeanPostProcessor 、有判断当前当前bean是否需要跳过代理创建过程,shouldSkip时会获取当前所有的Advisor类,也就是我们上面加入的哪些#0、#1、#2等 然后会依次对这些Advisor进行创建 Advisor,如果是pointCut的bean会设置跳过,需要代理的类是不会被跳过的 2.在bpp的after方法中,AspectJAwareAdvisorAutoProxyCreator会执行wrapIfNecessary进行代理对象的创建
AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary向beanFactory注册AspectJAwareAdvisorAutoProxyCreator(internalAutoProxyCreator)
getBean(beanName)
proxyFactory.setTargetSource(targetSource)添加代理工厂的代理类
getCallbacks(rootClass)获取回调拦截器,这里会添加DynamicAdvisedInterceptor
doGetBean
createAdviceDefinition两个bean最终包装为AbstractAspectJAdvice通知对象
ConfigBeanDefinitionParser#parse
AspectJAroundAdvice#invoke
invokeJoinpoint()执行原本的方法
解析aop-config
截器链中的拦截器是否全部执行完毕
findAdvisorsThatCanApply获取所有该bean匹配的advisor
shouldSkip中调用findCandidateAdvisors() 会生成advisor对象,如果缓存中有 直接从缓存中取获取所有没有被@PointCut修饰的方法,并排序(@Around修饰 -> @Before -> @After -> @AfterReturning -> @AfterThrowing)依次为每个被注解修饰的方法生成Advisor对象 1.获取AspectJExpressionPointcut对象 2.实例化InstantiationModelAwarePointcutAdvisorImpl(继承自Advisor)对象将切面所有的通知类放入advisorsCache缓存中 key= 切面beanName values= advisors在BPP的after方法中wrapIfNecessary,会新增一个ExposeInvocationInterceptor
Object retVal = mi.proceed();
MethodLocatingFactoryBean
sortAdvisors对Advisor进行拓扑排序
createBean -> resolveBeforeInstantiation
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex)获取拦截器链中的拦截器
new RootBeanDefinition(SimpleBeanFactoryAwareAspectInstanceFactory.class)
preInstantiateSingletons循环创建单例对象
处理AOP的是AbstractAutoProxyCreator
SimpleBeanFactoryAwareAspectInstanceFactory
是实现自InstantiationAwareBeanPostProcessor
AspectJAfterAdvice#invoke
postProcessBeforeInstantiation执行BPP的before方法
finally
super.findCandidateAdvisors()xml方式定义的Advisor
extendAdvisors(eligibleAdvisors)如果获取的Advosor不为空该方法会添加ExposeInvocationIntecepter这个Advosor
0:ExposeInvocationInterceptor(确保多个切面 之间进行调用MethodInvocation不会乱)1:AspectJArountAdvice2:MethodBeforeAdviceInteceptor3:AspectJAfterAdvice4:AfterReturningAdviceInterceptor5:AspectJAfterThrowingAdvice
ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi将MethodInvocation强转为ProxyMethodInvocation
findCandidateAdvisors();获取当前类所有的Advisor,然后放到集合中
找到系统中所有的Advisor类型包含父类,然后遍历生成
finishBeanFactoryInitialization
AOP对象XML创建过程
收藏
收藏
0 条评论
下一页