Spring AOP 源码解析系列,建议你们按顺序阅读,欢迎讨论spring
框架存在的意义,简单来讲就是将复杂的底层实现封装起来,并提供便捷的外部接口供用户使用。对于Spring AOP而言,不管是ProxyFactory仍是ProxyFactoryBean,都不能知足实际业务中复杂的应用,用户不可能对每一个使用AOP代理的类进行配置。这时经过必定规则自动发现和代理天然应运而生。在spring-aop工程的autoproxy目录构成了Spring AOP自动代理的基础,AbstractAutoProxyCreator是自动代理实现的抽象基类,BeanNameAutoProxyCreator和DefaultAdvisorAutoProxyCreator则是Spring提供的两个实现。数组
自动代理的实现原理同ProxyFactoryBean中使用FactoryBean扩展不一样,而是经过BeanPostProcessor扩展对Bean对象的建立过程进行控制来实现AOP代理。抽象基类AbstractAutoProxyCreator实现了BeanPostProcessor的子接口SmartInstantiationAwareBeanPostProcessor。先来了解下这个子接口。缓存
咱们常说起的BeanPostProcessor扩展并非只有BeanPostProcessor一个接口,而是由其造成的多层接口体系,对Bean对象在IOC容器的建立过程的各个节点扩展造成的体系。这里只展现下SmartInstantiationAwareBeanPostProcessor的类结构。app
BeanPostProcessor框架
InstantiationAwareBeanPostProcessoride
SmartInstantiationAwareBeanPostProcessor函数
而对于Spring AOP的自动代理,处理的阶段有两个,对象实例化前扩展和初始化后扩展。post
在对象实例化前(postProcessBeforeInstantiation)的扩展中,主要对配置了customTargetSourceCreators属性的状况进行处理,而默认的处理都是在初始化后(postProcessAfterInitialization)扩展里执行的。ui
所谓的customTargetSourceCreators属性是在AbstractAutoProxyCreator中的一个TargetSourceCreator数组,用来对代理对象target的封装类TargetSource的生成进行自定义。spring内置的TargetSourceCreator有两个:LazyInitTargetSourceCreator和QuickTargetSourceCreator。this
LazyInitTargetSourceCreator:建立的代理对象并无初始化,直到第一次调用时才进行初始化
QuickTargetSourceCreator:根据beanName的不一样前缀建立三种经常使用的TargetSource类型(bean必须为多例)
来看下核心代码
if (beanName != null) { // 获取自定义TargetSource TargetSource targetSource = getCustomTargetSource(beanClass, beanName); if (targetSource != null) { this.targetSourcedBeans.add(beanName); // 获取拦截器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource); // 建立代理对象 Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } }
第一步获取定义TargetSource,即遍历全部自定义TargetSourceCreator,调用getTargetSource方法返回TargetSource。
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { // We can't create fancy target sources for directly registered singletons. if (this.customTargetSourceCreators != null && this.beanFactory != null && this.beanFactory.containsBean(beanName)) { for (TargetSourceCreator tsc : this.customTargetSourceCreators) { TargetSource ts = tsc.getTargetSource(beanClass, beanName); if (ts != null) { // Found a matching TargetSource. if (logger.isDebugEnabled()) { logger.debug("TargetSourceCreator [" + tsc + " found custom TargetSource for bean with name '" + beanName + "'"); } return ts; } } } // No custom TargetSource found. return null; }
第二步获取拦截器由子类实现,根据不一样的方式获取当前bean的拦截器,在后文以子类DefaultAdvisorAutoProxyCreator为例详细介绍。
第三步建立代理对象,经过建立ProxyFactory的方式完成,原理细节见ProxyFactory,来简单看下它的实现。
protected Object createProxy( Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) { ProxyFactory proxyFactory = new ProxyFactory(); // copy代理配置,如proxyTargetClass,exposeProxy等 proxyFactory.copyFrom(this); // proxyTargetClass=false时 if (!proxyFactory.isProxyTargetClass()) { // 再次确认是否要代理类对象 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } // 不须要则获取其代理接口集合 else { evaluateProxyInterfaces(beanClass, proxyFactory); } } // 将全部拦截器封装成Advisor Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); for (Advisor advisor : advisors) { proxyFactory.addAdvisor(advisor); } proxyFactory.setTargetSource(targetSource); // 扩展点,支持子类对ProxyFacory扩展 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } // 建立代理对象 return proxyFactory.getProxy(getProxyClassLoader()); }
能够说逻辑很是清晰,最后使用ProxyFactory建立代理对象也是使用ProxyFactory统一的API。若是最终返回的代理对象不为空,则直接返回代理对象,再也不执行IOC中的对象属性注入和初始化等操做了。
若是并无设置自定义TargetSourceCreator,代理对象就会在原始对象初始化完成后建立。
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
wrapIfNecessary方法执行代理的核心操做。
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (beanName != null && this.targetSourcedBeans.contains(beanName)) { return bean; } if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } // AOP体系的子类不被代理(Advisor,Advice等) if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // Create proxy if we have advice. // 获取拦截器 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 建立代理对象 Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); return proxy; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; }
实现过程基本同以前的一直,由子类返回拦截器集合,建立ProxyFactory对象进行代理。
在基类AbstractAutoProxyCreator中经过BeanPostProcessor扩展的方式,使得bean在建立过程当中完成被代理。代理的框架已有AbstractAutoProxyCreator基本完成,留给子类的是获取拦截器getAdvicesAndAdvisorsForBean方法的具体实现。咱们以DefaultAdvisorAutoProxyCreator为例,了解下Spring AOP是如何完成自动发现和过滤切面的。
DefaultAdvisorAutoProxyCreator的获取拦截器实现其实由其抽象基类AbstractAdvisorAutoProxyCreator实现。
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); }
实际操做有findEligibleAdvisors执行
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { // 寻找全部Advisor候选者 List<Advisor> candidateAdvisors = findCandidateAdvisors(); // 获取匹配当前bean的Advisor List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { // 对Advisor排序 eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
主要过程分为两步,第一步寻找全部Advisor候选者,即自动发现切面,第二部筛选当前bean的Advisor。
findCandidateAdvisors由BeanFactoryAdvisorRetrievalHelper帮助类执行,原理就是从BeanFactory及其全部父级BeanFactory中寻找类型为Advisor的类,并执行getBean实例化。
public List<Advisor> findAdvisorBeans() { // Determine list of advisor bean names, if not cached already. String[] advisorNames = null; synchronized (this) { advisorNames = this.cachedAdvisorBeanNames; if (advisorNames == null) { // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the auto-proxy creator apply to them! // 寻找Advisor类型的bean advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); this.cachedAdvisorBeanNames = advisorNames; } } if (advisorNames.length == 0) { return new LinkedList<Advisor>(); } List<Advisor> advisors = new LinkedList<Advisor>(); for (String name : advisorNames) { if (isEligibleBean(name)) { if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isDebugEnabled()) { logger.debug("Skipping currently created advisor '" + name + "'"); } } else { try { // getBean实例化 advisors.add(this.beanFactory.getBean(name, Advisor.class)); } catch (BeanCreationException ex) { Throwable rootCause = ex.getMostSpecificCause(); if (rootCause instanceof BeanCurrentlyInCreationException) { BeanCreationException bce = (BeanCreationException) rootCause; if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) { if (logger.isDebugEnabled()) { logger.debug("Skipping advisor '" + name + "' with dependency on currently created bean: " + ex.getMessage()); } // Ignore: indicates a reference back to the bean we're trying to advise. // We want to find advisors other than the currently created bean itself. continue; } } throw ex; } } } } return advisors; }
findAdvisorsThatCanApply筛选Advisor是由AopUtils类实现。对不一样类型的Advisor进行不一样的处理,如IntroductionAdvisor和PointcutAdvisor。
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new LinkedList<Advisor>(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } boolean hasIntroductions = !eligibleAdvisors.isEmpty(); for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { // already processed continue; } // 匹配Advisor是否适用当前bean if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
其中canApply方法执行实际的匹配操做,细节部分主要是对切入点Pointcut和bean的匹配,有兴趣的能够本身深刻研究其匹配过程。
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } }
至此也就完成了bean适用的Advisor切面的自动发现与筛选,最后由ProxyFactory完成代理建立。
在看自动代理源码的过程当中,忽然注意到SmartInstantiationAwareBeanPostProcessor接口中的getEarlyBeanReference方法,它是Spring处理循环依赖时返回**未建立完(只实例化未作依赖注入)**Bean的扩展。关于循环依赖能够去Bean的循环依赖一章去详细了解,这里只作简单的说明。
有两个单例Bean,A和B,A中引用了B,B中引用了A。Spring对这种相互依赖作了特殊的处理,即在对象实例化后缓存一份key为beanName的ObjectFactory,ObjectFactory中的getObject方法返回当前建立对象的引用。
// 支持单例依赖循环 if (earlySingletonExposure) { // 添加Early对象缓存 addSingletonFactory(beanName, new ObjectFactory<Object>() { [@Override](https://my.oschina.net/u/1162528) public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); }
这里假设先建立A对象实例,当A进行依赖注入时,须要B对象,则会经过getBean方法建立B对象。此时A并无建立完成,但在Early缓存中存有A的引用,于是当B对象进行依赖注入A时,直接返回A对象的Early引用,从而不会形成陷入无休止的依赖注入循环中。
在getEarlyBeanReference方法中,不只只是返回对象引用,还有一个扩展点,支持SmartInstantiationAwareBeanPostProcessor接口中的getEarlyBeanReference方法对返回的对象引用进行修改。
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { Object exposedObject = bean; if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; // 扩展点,对Early对象进行修改 exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); if (exposedObject == null) { return exposedObject; } } } } return exposedObject; }
回到AOP的自动代理上,在AbstractAutoProxyCreator中实现了getEarlyBeanReference扩展
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { this.earlyProxyReferences.add(cacheKey); } return wrapIfNecessary(bean, beanName, cacheKey); }
这里将标识惟一bean的cacheKey添加到earlyProxyReferences中,在以后bean的初始化中将颇有用。而后执行wrapIfNecessary返回bean的代理对象,于是若是存在循环依赖,则依赖注入的就是真正的代理对象。
在对象执行完依赖注入后,进行初始化操做,会调用初始化后扩展postProcessAfterInitialization方法,再来关注下AbstractAutoProxyCreator此方法的实现。
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); // 判断early引用中是否包含cacheKey if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
它判断了earlyProxyReferences中不包含当前bean的cacheKey才会执行代理操做,也就是说,若是存在循环依赖时,代理对象在getEarlyBeanReference时就建立了,而在初始化后直接跳过了,返回的bean是原始的对象。
你可能会问,既然这里返回的不是代理对象,那代理对象最后是怎样返回的呢?
Spring在对象进行初始化后,对存在循环依赖的又作了巧妙的处理。
if (earlySingletonExposure) { // 若是存在循环依赖,则返回的为代理对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { // 循环依赖下,通过初始化后的对象同原始对象一致 // 于是将代理对象赋给最终返回的对象引用 if (exposedObject == bean) { exposedObject = earlySingletonReference; } } }
这里的设计非常巧妙,须要结合依赖循环的处理,AOP对象的处理统一来理解。同时对循环依赖时,不直接缓存对象,而是经过ObjectFactory的方式有了更深的理解。有兴趣的同窗能够反复琢磨一下。
2017/12/24更新
回头再看这个循环依赖的点,仍是花了一点时间来回翻了下源码才理解,所以再补充记录下。getSingleton(beanName, false)方法,当不存在循环依赖时,会返回null,而存在循环依赖时,返回的是ObjectFactory的getEarlyBeanReference方法返回的对象。原始的bean对象通过getEarlyBeanReference方法后,可能存在SmartInstantiationAwareBeanPostProcessor处理器,在其getEarlyBeanReference方法中被改变了,好比AbstractAutoProxyCreator中会返回代理对象。而在AbstractAutoProxyCreator的实现中,使用cacheKey保证了生成的代理对象是单例的。所以当if (exposedObject == bean)判断时会返回true,从而getBean方法返回的对象就是真正的代理对象。此时还有一个疑问,代理对象并无进行属性的依赖注入以及init-method等的初始化啊?其实代理对象没有必要去复制原始对象的内部结构,由于它持有原始对象的引用,而且实际调用方法是交由原始对象去处理的。
Spring AOP的自动代理,它同ProxyFactoryBean采用了不一样的扩展方式。FactoryBean的扩展思路很是清晰,在工厂ProxyFactoryBean建立完成后直接根据其配置动态生成不一样的代理对象,适用于简单的配置,但在ApplicationContext高级容器中,就须要经过BeanPostProcessor扩展进行更细粒度的操做,从而支持复杂的业务配置。而接下来要讨论的AspectJ整合Spring的基础实现,就来自于Spring AOP的自动代理。