1. SpringBoot 中代理对象的创建者
Spring 是基于动态代理实现的 aop,其核心在于代理类增强目标类的功能。这样对于每一个目标类,如何创建其代理对象就极为关键。从源码来看,Spring 中代理对象的创建都离不开AnnotationAwareAspectJAutoProxyCreator
,这个类实现了 BeanPostProcessor
接口,会在每个bean实例创建时检查该bean是否需要创建代理,需要的话就创建相应的代理
基于 SpringBoot 的自动配置机制,在注解
@EnableAspectJAutoProxy
的定义中会通过@Import(AspectJAutoProxyRegistrar.class)
将注册类引入,而在AspectJAutoProxyRegistrar
的注册 bean 定义方法中会通过代码AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()
最终将AnnotationAwareAspectJAutoProxyCreator
注册到 bean 工厂中
AnnotationAwareAspectJAutoProxyCreator
的继承结构如下:
2. 代理对象创建流程
2.1 代理对象创建者的注册
-
SpringBoot 启动过程中会将各个自动配置类加载进容器,其中就包括了 Aop 的自动配置类
AopAutoConfiguration
。在该类会根据配置属性spring.aop.auto
来决定是否启用自动代理,一般默认为启用。另外也会启动注解@EnableAspectJAutoProxy
来决定代理的实现方式@Configuration @ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class, AnnotatedElement.class }) @ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true) public class AopAutoConfiguration { @Configuration @EnableAspectJAutoProxy(proxyTargetClass = false) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false) public static class JdkDynamicAutoProxyConfiguration { } @Configuration @EnableAspectJAutoProxy(proxyTargetClass = true) @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true) public static class CglibAutoProxyConfiguration { } }
-
@EnableAspectJAutoProxy
通过@Import(AspectJAutoProxyRegistrar.class)
引入了注册类AspectJAutoProxyRegistrar
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(AspectJAutoProxyRegistrar.class) public @interface EnableAspectJAutoProxy { boolean proxyTargetClass() default false; boolean exposeProxy() default false; }
-
AspectJAutoProxyRegistrar
实现了接口ImportBeanDefinitionRegistrar
, 在框架启动过程中会回调其实现的接口方法registerBeanDefinitions()
,将相关 bean 注册到容器中,这个过程实际是由AopConfigUtils
实现@Override public void registerBeanDefinitions( AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry); AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class); if (enableAspectJAutoProxy != null) { if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) { AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); } if (enableAspectJAutoProxy.getBoolean("exposeProxy")) { AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry); } } }
-
AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary()
最终调用到其内部方法registerAspectJAnnotationAutoProxyCreatorIfNecessary()
,将AnnotationAwareAspectJAutoProxyCreator
bean 定义注册到了 bean 工厂中@Nullable public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) { return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source); }
2.2 代理对象创建的入口
-
容器启动的过程中,会在环境准备完成的时候进行 bean 的创建工作。这部分可参考 Spring 启动流程源码解析,在刷新容器的时候
AbstractApplicationContext#refresh()
方法被调用,该方法会调用到AbstractApplicationContext#registerBeanPostProcessors()
将所有实现了BeanPostProcessor
接口的类从 bean 工厂注册到容器中。bean 对象的创建最终在方法finishBeanFactoryInitialization()
完成protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } ......
-
beanFactory.getBean()
的实现在AbstractBeanFactory
中,其关键处理如下:- 调用到
AbstractBeanFactory#doGetBean()
方法完成对象创建,其中包括了属性注入和BeanPostProcessor
前后置的处理 - 进一步调用
getObjectForBeanInstance()
方法对 bean 对象做处理
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { ...... bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } ...... }
- 调用到
-
getObjectForBeanInstance()
会判断当前 bean 实例的相关属性,如果 bean 实例是 FactoryBean 的对象,说明真正的目标对象还没有创建出来,需要通过方法getObjectFromFactoryBean()
去获取目标 beanprotected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name)) { if (beanInstance instanceof NullBean) { return beanInstance; } if (!(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
-
getObjectFromFactoryBean()
的实现在FactoryBeanRegistrySupport
中,根据 boolean 参数shouldPostProcess
来决定是否对 bean 实例调用postProcessObjectFromFactoryBean()
方法进行处理protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache.get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName); // Only post-process and store if not put there already during getObject() call above // (e.g. because of circular reference processing triggered by custom getBean calls) Object alreadyThere = this.factoryBeanObjectCache.get(beanName); if (alreadyThere != null) { object = alreadyThere; } else { if (shouldPostProcess) { if (isSingletonCurrentlyInCreation(beanName)) { // Temporarily return non-post-processed object, not storing it yet.. return object; } beforeSingletonCreation(beanName); try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's singleton object failed", ex); } finally { afterSingletonCreation(beanName); } } if (containsSingleton(beanName)) { this.factoryBeanObjectCache.put(beanName, object); } } } return object; } } else { Object object = doGetObjectFromFactoryBean(factory, beanName); if (shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex); } } return object; } }
-
postProcessObjectFromFactoryBean()
方的实现在AbstractAutowireCapableBeanFactory
中,在该方法内会调用其内部方法applyBeanPostProcessorsAfterInitialization()
遍历调用BeanPostProcessor
实现类的postProcessAfterInitialization()
方法@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
-
上文已经提及
AnnotationAwareAspectJAutoProxyCreator
的继承结构,以上步骤最终会调用到AnnotationAwareAspectJAutoProxyCreator
的超类AbstractAutoProxyCreator
的postProcessAfterInitialization()
方法,在该方法内调用的wrapIfNecessary()
方法就是创建代理对象的核心入口public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
2.3 切面的解析与适配
-
AbstractAutoProxyCreator#wrapIfNecessary()
方法中首先会调用getAdvicesAndAdvisorsForBean()
方法尝试去获取能够应用到给定 bean 上的切面,这个方法由其子类AbstractAdvisorAutoProxyCreator
实现;之后通过createProxy()
方法将切面应用到 bean 上去创建代理对象protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { ...... // Create proxy if we have advice. // 1. 尝试获取能够应用到 bean 上的切面 Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 2. 将切面应用到 bean 上创建代理对象 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; }
-
AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean()
方法调用其内部方法findEligibleAdvisors()
去搜索切面,其中又包含了两个步骤,第一步是findCandidateAdvisors()
去搜索候选的切面,第二步是findAdvisorsThatCanApply()
从候选切面中选择能够应用到给定 bean 的切面protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }
-
搜索候选切面的方法
findCandidateAdvisors()
在AnnotationAwareAspectJAutoProxyCreator
中实现,流程是先调用父类的同名方法初步获取切面列表,然后通过BeanFactoryAspectJAdvisorsBuilder
去创建切面@Override protected List<Advisor> findCandidateAdvisors() { // Add all the Spring advisors found according to superclass rules. List<Advisor> advisors = super.findCandidateAdvisors(); // Build Advisors for all AspectJ aspects in the bean factory. if (this.aspectJAdvisorsBuilder != null) { advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); } return advisors; }
-
BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors()
方法主要流程是首先调用this.advisorFactory.isAspect(beanType)
方法根据注解@Aspect
等条件判断给定bean是否是切面类,其次调用this.advisorFactory.getAdvisors(factory)
去获取增强切面Advisor
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = this.aspectBeanNames; ...... // We must be careful not to instantiate beans eagerly as in this case they // would be cached by the Spring container but would not have been weaved. Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } } ...... }
-
getAdvisors()
的实现为ReflectiveAspectJAdvisorFactory#getAdvisors()
,该方法会调用getAdvisorMethods(aspectClass)
获取切面类的所有增强方法
,之后调用getAdvisor()
将每个增强方法组装为一个增强切面Advisor
@Override public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) { ...... List<Advisor> advisors = new ArrayList<>(); for (Method method : getAdvisorMethods(aspectClass)) { Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName); if (advisor != null) { advisors.add(advisor); } } ...... return advisors; }
-
getAdvisor()
返回一个InstantiationModelAwarePointcutAdvisorImpl
实例,该实例保存了切面的类名,增强方法的方法名,切入点等信息。切入点AspectJExpressionPointcut
为getPointcut()
返回值,该方法会解析增强方法上的注解@Before
@After
等,将注解的属性保存为切入点表达式
,用于匹配被增强的方法public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) { validate(aspectInstanceFactory.getAspectMetadata().getAspectClass()); AspectJExpressionPointcut expressionPointcut = getPointcut( candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass()); if (expressionPointcut == null) { return null; } return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod, this, aspectInstanceFactory, declarationOrderInAspect, aspectName); }
-
至此搜索候选切面完成,接下来就是 步骤2 中
findAdvisorsThatCanApply()
从候选切面中选择能够应用到给定 bean 的切面。可以看到其核心代码为调用AopUtils.findAdvisorsThatCanApply()
方法protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
-
AopUtils
判断切面是否可以应用到 bean 对象的核心方法是canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions)
,这个方法会从切入点实例
中获取方法匹配者 MethodMatcher
,然后调用methodMatcher.matches()
去完成匹配判断public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { ...... MethodMatcher methodMatcher = pc.getMethodMatcher(); ...... for (Class<?> clazz : classes) { Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
2.4 代理对象的最终创建
-
回到
AbstractAutoProxyCreator#wrapIfNecessary()
,经过以上流程 Spring 已经为给定的 bean 对象找到了可应用的切面列表,接下来就是调用createProxy()
创建代理对象将切面应用到 bean 上protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { ...... if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); // 2. 将切面应用到 bean 上创建代理对象 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; }
-
createProxy()
中首先是新建代理工厂ProxyFactory
,之后设置代理工厂的各项属性,将切面列表和目标类都设置进去,最后调用proxyFactory.getProxy(getProxyClassLoader())
去生成代理对象protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } ProxyFactory proxyFactory = new ProxyFactory(); proxyFactory.copyFrom(this); if (!proxyFactory.isProxyTargetClass()) { if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { evaluateProxyInterfaces(beanClass, proxyFactory); } } Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } return proxyFactory.getProxy(getProxyClassLoader()); }
-
创建代理对象主要通过代理工厂来进行,而对于不同的代理方式,又分为了
JdkDynamicAopProxy
和ObjenesisCglibAopProxy
,其中ObjenesisCglibAopProxy
继承了CglibAopProxy
。此处以CglibAopProxy
代理为例,创建代理对象最终调用到getProxy()
方法,其中极为关键的流程为调用getCallbacks()
方法获取目标方法被 aop 拦截的回调函数列表@Override public Object getProxy(@Nullable ClassLoader classLoader) { ...... // 获取拦截回调函数 Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getClass(); } // fixedInterceptorMap only populated at this point, after getCallbacks call above enhancer.setCallbackFilter(new ProxyCallbackFilter( this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset)); enhancer.setCallbackTypes(types); // Generate the proxy class and create a proxy instance. return createProxyClassAndInstance(enhancer, callbacks); ...... }
-
getCallbacks()
会创建一个用于实现 aop 的拦截方法类DynamicAdvisedInterceptor
,当目标方法被调用的时候,该拦截类的方法DynamicAdvisedInterceptor#intercept()
就会被触发,从而完成 Aop 拦截增强目标方法的逻辑private Callback[] getCallbacks(Class<?> rootClass) throws Exception { ...... // Choose an "aop" interceptor (used for AOP calls). Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised); ...... Callback[] mainCallbacks = new Callback[] { aopInterceptor, // for normal advice targetInterceptor, // invoke target without considering advice, if optimized new SerializableNoOp(), // no override for methods mapped to this targetDispatcher, this.advisedDispatcher, new EqualsInterceptor(this.advised), new HashCodeInterceptor(this.advised) }; ...... return callbacks; }