Spring源码窥探之:注解方式的AOP原理

AOP入口代码分析

经过注解的方式来实现AOP
1. @EnableAspectJAutoProxy经过@Import注解向容器中注入了AspectJAutoProxyRegistrar这个类,而它在容器中的名字是org.springframework.aop.config.internalAutoProxyCreator。
2. AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,因此能够向容器中注册Bean的定义信息。
3. 经过跟踪AspectJAutoProxyRegistrar,咱们发现它向容器中注册了AnnotationAwareAspectJAutoProxyCreator的定义信息。
4. 观察AnnotationAwareAspectJAutoProxyCreator的继承结构图,发现,它既是一个后置处理器,又是一个BeanFactoryAware的实现类。
因此咱们能够分析:
1、 AnnotationAwareAspectJAutoProxyCreator做为后置处理器作了什么?
2、 做为Aware作了什么?

继承结构分析

AnnotationAwareAspectJAutoProxyCreator的继承结构图,以下: AnnotationAwareAspectJAutoProxyCreator -> extends AspectJAwareAdvisorAutoProxyCreator -> extends AbstractAdvisorAutoProxyCreator -> extends AbstractAutoProxyCreator -> implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware 【可见AnnotationAwareAspectJAutoProxyCreator是一个后置处理器,也是一个Aware】 AbstractAutoProxyCreator做为一个抽象类,实现了SmartInstantiationAwareBeanPostProcessor和BeanFactoryAware 故,咱们分别在他们的实现方法上加断点,好比:postProcessBeforeInstantiation()和setBeanFactory()

 断点调试

首先来到AbstractAutoProxyCreator的setBeanFactory(),查看IDE的调用栈,如图:

1. 传入配置类,建立IOC容器 2. 注册配置类,调用refresh()刷新容器 3. registerBeanPostProcessors(beanFactory)注册Bean的后置处理器,来拦截Bean的建立。 1) 先获取IOC容器已经定义了的须要建立对象的全部BeanPostProcessor 2) 给容器中添加另外其余的BeanPostProcessor 3) 优先注册实现了PriorityOrdered接口的BeanPostProcessor 4) 再注册实现Order接口的BeanPostProcessor 5) 最后注册没实现任何接口的BeanPostProcessor 6) 注册BeanPostProcessor,实际上就是建立BeanPostProcessor对象,并保存在容器中 如何建立名字叫internalAutoProxyCreator【AnnotationAwareAspectJAutoProxyCreator】的后置处理器? 1) 先来建立Bean的实例 2) populateBean()给Bean的属性赋值 3) initializeBean()初始化Bean 1) invokeAwareMethods(beanName, bean)处理Aware接口的方法回调 2) applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName) 拿到全部的BeanPostProcessor并执行postProcessBeforeInitialization 3) invokeInitMethods(beanName, wrappedBean, mbd)执行自定义的初始化方法,好比init()和destroy() 4) applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName) 拿到全部的BeanPostProcessor并执行postProcessAfterInitialization 4) BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】建立成功 7) 把BeanPostProcessor注册并添加到BeanFactory中 ==========以上是建立和注册AnnotationAwareAspectJAutoProxyCreator的过程==========

 AnnotationAwareAspectJAutoProxyCreator做为后置处理器作了什么?

4. finishBeanFactoryInitialization(beanFactory)完成BeanFactory的初始化工做,建立剩下的单实例Bean 1)遍历获取全部的Bean,依次建立对象getBean(beanName) getBean -> doGetBean() -> getSingleton() 2)如何建立Bean? 【首先说明:上面注册过的后置处理器AnnotationAwareAspectJAutoProxyCreator会在全部Bean建立以前进行拦截调用,由于 AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口】 1)先从缓存中获取当前Bean,若是能获取到,说明Bean是以前被建立过了的,直接使用,不然再进行建立 只要被建立过的Bean都会被缓存起来 2)createBean()建立Bean的实例,过程以下: 1)resolveBeforeInstantiation(beanName, mbdToUse)这一步是尝试返回Bean的代理对象 但愿后置处理器在此能返回一个代理对象,若是不能就调用doCreateBean()建立对象 如何返回代理对象呢? if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } 【注意:这里的applyBeanPostProcessorsBeforeInstantiation不一样于BeanPostProcessor的postProcessBeforeInitialization】 【applyBeanPostProcessorsBeforeInstantiation和applyBeanPostProcessorsAfterInitialization属于InstantiationAwareBeanPostProcessor的方法 而InstantiationAwareBeanPostProcessor是在建立Bean对象实例以前进行调用,目的是在建立Bean对象以前首先尝试返回代理对象, 但BeanPostProcessor的两个方法则是在Bean对象建立完成,进行初始化的先后才进行调用,他们两个执行的时机不同BeanPostProcessor的执行稍微晚一点】 2)doCreateBean(beanName, mbdToUse, args)此方法才是真正的建立一个Bean实例,建立实例的流程和上面同样

分析InstantiationAwareBeanPostProcessor的两个方法

AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor因此每个Bean在建立以前,都会通过 postProcessBeforeInstantiation()方法。固然也包括被切的实体。 1. 每一个Bean在建立以前都会通过postProcessBeforeInstantiation()过程分析: 1)判断当前Bean是否在advisedBeans(里面保存了须要加强的Bean)中。 this.advisedBeans.containsKey(cacheKey) 2)判断当前Bean是不是基础类型(Advice,Pointcut,Advisor,AopInfrastructureBean)。 isInfrastructureClass(beanClass) 3)是否须要跳过?(好像永远要跳过^_^) shouldSkip(beanClass, beanName) 这个方法首先获取候选的加强器List<Advisor> candidateAdvisors = findCandidateAdvisors(); 每个Advisor的类型是InstantiationModelAwarePointcutAdvisor,并非AspectJPointcutAdvisor 2. 通过postProcessBeforeInstantiation()尝试建立对象出来之后,进入AbstractAutoProxyCreator的postProcessAfterInitialization方法 postProcessAfterInitialization方法中有一个wrapIfNecessary(bean, beanName, cacheKey)开始进行包装Bean,点击进入: 1)Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); 找到全部的加强器,并获取到能在该Bean使用的加强器,而后顺便排序(目的是为了有序的切入) 2)保存当前Bean到advisedBeans中 this.advisedBeans.put(cacheKey, Boolean.TRUE) 3)若是当前Bean须要加强,就建立当前Bean的代理对象 Object proxy = createProxy(...),如何建立?以下: 1. 获取全部通知方法 2. 保存到proxyFactory中 3. 建立代理对象,Spring自动决定 new JdkDynamicAopProxy(config);实现接口 ObjenesisCglibAopProxy(config);没有实现接口 4)经过以上三步,wrapIfNecessary()方法会返回一个代理Bean而且放到容器中,当调用目标方法的时候,其实是代理类在调用
相关文章
相关标签/搜索