图解springAop源码

类的关系在这里插入图片描述
AbstractAutoProxyCreator .ProxyFactory ProxyFactory DefaultAopProxyFactory AopProxy 创建一个代理工程对象ProxyFactory 设置ProxyFactory值,Advisor列表,targetSource等。 复制当前ProxyConfig代理配置对象给ProxyFactory。 注:AbstractAutoProxyCreator继承ProxyConfig,所以可以把this对象 构建AbstractAutoProxyCreator配置的Advisor列表. buildAdvisors(beanName, specificInterceptors) 自定义一下代理工程配置,customizeProxyFactory(proxyFactory) 创建代理对象 获取当前的aop代理工厂AopProxyFactory,createAopProxy() 并通过ProxyFactory的创建AopProxy, 如果该bean是接口类, 创建一个JdkDynamicAopProxy,否则创建ObjenesisCglibAopProxy。 createAopProxy(AdvisedSupport config) 通过aop代理创建代理对象 返回aop代理对象 AbstractAutoProxyCreator .ProxyFactory ProxyFactory DefaultAopProxyFactory AopProxy postProcessBeforeInitialization生成对象过程

p s : \color{blue}{ps:} ps: 搞了半天还是分别通过JdkDynamicAopProxy和ObjenesisCglibAopProxy两个类来生成代理对象。

ObjenesisCglibAopProxy Bean代理对象 调用者 DynamicAdvisedInterceptor 创建aop代理对象 创建Enhancer 获取回调函数列表callbacks(Callback), getCallbacks(Class<?> rootClass) 创建动态通知拦截器。DynamicAdvisedInterceptor, getCallbacks(Class<?> rootClass) 返回并设置Enhancer回调函数列表callbacks 创建代理对象bean, createProxyClassAndInstance(enhancer, callbacks)(这一步已经实例化代理方法了) 调用方法 调用对象的拦截器的拦截方法。 intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy),转下,拦截器调用过程(jdk和cglib共用) ObjenesisCglibAopProxy Bean代理对象 调用者 DynamicAdvisedInterceptor ObjenesisCglibAopProxy创建代理对象的过程
DynamicAdvisedInterceptor AdvisedSupport DefaultAdvisorChainFactory DefaultAdvisorAdapterRegistry CglibMethodInvocation 进入拦截器方法 获取当前的TargetSource。 this.advised.getTargetSource() 获取拦截器的InvokerInterceptor列表, tgetInterceptorsAndDynamicInterceptionAdvice(method, targetClass) 如果缓存已经存在,直接返回拦截器的方法拦截器MethodInterceptor列表 通过 DefaultAdvisorChainFactory获取列表,设置缓存, getInterceptorsAndDynamicInterceptionAdvice 获取Advisor适配器注册器, GlobalAdvisorAdapterRegistry.getInstance() 如果是PointcutAdvisor,匹配当前拦截的方法, 如果满足, 通过注册获取advisor的方法拦截器 如果是其他advisor, 通过注册适配器获取advisor的方法拦截器 获取当前的Advisord的Advice, 可以是BeforeAdvice,AfterReturningAdvice,ThrowsAdvice 根据Advice查找适配器,AdvisorAdapter 创建并返回方法拦截器 loop [遍历advisors列表] 返回拦截器的方法拦截器MethodInterceptor列表 通过拦截器MethodInterceptor列表构建CglibMethodInvocation对象 调用proceed方法完成调用链的调用,其实使用了递归的调用流程 DynamicAdvisedInterceptor AdvisedSupport DefaultAdvisorChainFactory DefaultAdvisorAdapterRegistry CglibMethodInvocation 拦截器调用过程(jdk和cglib共用)

在这里插入图片描述
在这里插入图片描述

DefaultListableBeanFactory AbstractAutowireCapableBeanFactory InstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessor AutowiredAnnotationBeanPostProcessor BeanPostProcessor 根据名字获取bean,如果单例beanMap中有已经有该bean直接返回 创建bean 根据name创建bean 实例化bean之前 给个机会后置处理器对对应的class的beanName进行实例化, 返回已经实例化的bean,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 返回后置处理器处理完的bean实例化对象 loop [遍历所有的InstantiationAwareBeanPostProcessor接口实现类的后置处理器] 如果处理结果为null直接跳过, 否则认为bean已经实例化成功, 容器不会对bean进行属性填充了和初始化了, 直接调用bean的后置处理器的方法applyBeanPostProcessorsAfterInitialization(bean, beanName) 常规创建bean。 doCreateBean(beanName, mbdToUse, args) 调用构造方法实例化bean 确定一个构造方法实例化bean,instantiateBean(beanName, mbd) 实例化bean完成 当前bean是否允许依赖循环, 提前暴露bean的ObjectFactory引用 获取对指定bean的早期访问的引用, 通常用于解析循环引用。getEarlyBeanReference(Object bean, String beanName) 把getEarlyBeanReference返回的设置到ObjectFactory三级缓存里面 loop [:遍历所有实现SmartInstantiationAwareBeanPostProcessor接口 后置处理器] 实例化bean完成 填充bean属性,这里会自动注入依赖的bean 获取bean定义的所有属性值 遍历所有的InstantiationAwareBeanPostProcessor接口实现类的后置处理器 给个机会后置处理器返回填充bean属性的值, postProcessProperties(pvs, bw.getWrappedInstance(), beanName),也可以自己填充bean的属性 填充完注解依赖注入的属性 初始化bean。 initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) 注入bean的各种Aware 给个机会后置处理器替换当前的bean,该bean已经填充完属性, 不会对bean再进行填充,postProcessBeforeInitialization(result, beanName) loop [:遍历所有的BeanPostProcessor接口实现类的后置处理器] 初始化bean,调用用户自定义初始化方法, 如果bean实现了InitializingBean,调用afterPropertiesSet方法 给个机会后置处理返回一个bean替换当前的bean, 当前bean已经填充完成属性,一般返回代理类的实现 loop [:遍历所有BeanPostProcessor后置处理器] 创建bean完成 DefaultListableBeanFactory AbstractAutowireCapableBeanFactory InstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessor AutowiredAnnotationBeanPostProcessor BeanPostProcessor bean的生命周期
AbstractAutowireCapableBeanFactory AbstractAutoProxyCreator 实例化bean之前 遍历所有的bean前置处理器,给个机会后置处理器自定义实例化,如果返回不为空,直接使用后置处理器返回的bean 调用前置处理器方法,postProcessBeforeInstantiation(Class<?> beanClass, String beanName) 如果是Pointcut,AdviceAopInfrastructureBean,Advisor,AopInfrastructureBean基本类,不做代理,isInfrastructureClass(beanClass, beanName) 如果是bean的类有注解@Aspect,不做代理shouldSkip(beanClass, beanName), 把加入不需要代理的bean加入缓存,advisedBeans.put(beanName,false) 如果该bean不需要代理,返回null,结束 获取自定义TargetSource,TargetSourcegetCustomTargetSource(beanClass, beanName) 获取不到自定义TargetSource,结束 获取TargetSource所有的advisor,getAdvicesAndAdvisorsForBean() 为TargetSource生成代理对象,createProxy(beanClass, beanName, specificInterceptors, targetSource) 把代理对象加入缓存,this.proxyTypes.put(cacheKey, proxy.getClass()) 返回代理对象 加入beanMap里面,替换当前bean对象为代理对象 AbstractAutowireCapableBeanFactory AbstractAutoProxyCreator 实例化bean之前返回代理对象流程

p s : \color{blue}{ps:} ps:调用postProcessBeforeInstantiation(Class<?> beanClass, String beanName)返回代理对象,代理类后面的属性是无法进行依赖注入的属性值。所以除了TargetSource这种自定义返回的bean实例,代理bean都是在实例化依赖注入之后生成代理对象的。

AbstractAutowireCapableBeanFactory AnnotationAwareAspectJAutoProxyCreator 实例化bean之后,已经填充完属性了 遍历所有的bean后置处理器 如果后置处理器返回的对象不为空,直接替换bean对象 为配置了切面的信息的代理bean,生成代理对象,AnnotationAwareAspectJAutoProxyCreator 为bean生成代理对象,wrapIfNecessary(),转时序图(调用 wrapIfNecessary主要流程) 返回生成的代理对象 加入beanMap里面,替换当前bean对象为代理对象 AbstractAutowireCapableBeanFactory AnnotationAwareAspectJAutoProxyCreator spring实例化bean后返回代理对象流程
AnnotationAwareAspectJAutoProxyCreator wrapIfNecessary方法 findEligibleAdvisors方法 findAdvisorsThatCanApply方法 如果有必要为bean,生成代理对象 检查bean是否需要跳过代理 利用postProcessBeforeInitialization缓存的map,如果不需要代理,返回null 查找当前beanFactory可用的advisor,转时序图(查询beanFactory所有的advisor) 根据advisor的表达式筛选当前可用advisor 对可用的Advisor列表进行排序 返回排序后的Advisor列表 如果Advisor列表不为空,advisedBeans缓存bean,标记true,证明该类被代理了。 根据Advisor列表为bean创建代理对象 返回代理对象 AnnotationAwareAspectJAutoProxyCreator wrapIfNecessary方法 findEligibleAdvisors方法 findAdvisorsThatCanApply方法 调用 wrapIfNecessary主要流程

由上面可以得出spring的aop无非就是扫描注解@Aspect 注解的类,再扫描其中的

AnnotationAwareAspectJAutoProxyCreator BeanFactoryAspectJAdvisorsBuilder AspectJAdvisorFactory 调用父类的findEligibleAdvisors查询xml可用配置的advisor。这里需要兼容xml配置。 调用buildAspectJAdvisors()查找注解配置的advisor 遍历当前BeanFactory所有bean 调用isAspect()判断是否切面配置类,如果包含注解@Aspect,直接返回true,否则为false 把切面bean加入缓存aspectNames中 解析切面bean的类的元数据 AnnotationAwareAspectJAutoProxyCreator BeanFactoryAspectJAdvisorsBuilder AspectJAdvisorFactory 注解切面查询bean可用的advisor(一)
BeanFactoryAspectJAdvisorsBuilder AspectJAdvisorFactory MetadataAwareAspectInstanceFactory ReflectiveAspectJAdvisorFactory 调用getAdvisors()获取Advisor列表 调用getAspectMetadata().getAspectClass()获取切面类class 调用validate()校验切面类的注解配置是否正确 遍历切面类所有方法,调用getAdvisor(),获取Advisor 调用getPointcut解析方法的注解(Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class),构建AspectJExpressionPointcut对象 通过AspectJExpressionPointcut对象构建InstantiationModelAwarePointcutAdvisorImpl,该对象继承PointcutAdvisor 把PointcutAdvisor加入AdvisorList 返回Advisor列表 BeanFactoryAspectJAdvisorsBuilder AspectJAdvisorFactory MetadataAwareAspectInstanceFactory ReflectiveAspectJAdvisorFactory 查询bean可用的advisor(二)
bean工厂 aop代理生成类 解析切面配置类 生成代理工厂类 bean代理类 拦截方法调用类 bean初始化完成之后 需要为bean生成代理完成aop代理类 第一步 解析配置 @Aspect 注解的类 被解析成 InstantiationModelAwarePointcutAdvisorImpl 是一个InstantiationModelAwarePointcutAdvisor @Pointcut注解的方法被解析成 AspectJExpressionPointcut, 这个类提供方法匹配器。 @AfterReturning注解的 方法被解析成 AspectJAfterReturningAdvice @Before注解的方法 被解析成AspectJMethodBeforeAdvice @Around 注解的方法 被解析成 AspectJAroundAdvice @After 注解的方法被解 析成 AspectJAfterAdvice @AfterThrowing 注解 的方法被解析成 AspectJAfterThrowingAdvice 因为InstantiationModelAwarePointcutAdvisorImpl封装以上所有属性 第二步 根据InstantiationModelAwarePointcutAdvisor生成代理对象, 返回代理类 第三步 当bean方法被调用时 为bean构建拦截器, AspectJAfterReturningAdvice 构建成AfterReturningMethodInterceptor AspectJMethodBeforeAdvice 构建成 BeforeMethodInterceptor 其他类似.. 拦截方法调用 bean工厂 aop代理生成类 解析切面配置类 生成代理工厂类 bean代理类 拦截方法调用类 注解和springAop对象的映射关系:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值