从入口分析spring和spring boot的aop proxy
boot入口类源码:
@EnableAsync@SpringBootApplication@MapperScan("com.ambition.business.mapper")public class SysApplication extends SpringBootServletInitializer {
public static void main(String[] args) { SpringApplication application = new SpringApplication(SysApplication.class); application.setBannerMode(Banner.Mode.OFF); application.run(args); }
@Override protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) { // 注意这里要指向原先用main方法执行的Application启动类 return builder.sources(SysApplication.class); }
}
先进入org.springframework.aop.config.AopNamespaceHandler:
进入org.springframework.aop.config.ConfigBeanDefinitionParser#parse:
private void configureAutoProxyCreator(ParserContext parserContext, Element element) { AopNamespaceUtils.registerAspectJAutoProxyCreatorIfNecessary(parserContext, element); }
进入org.springframework.aop.config.AopNamespaceUtils#registerAspectJAutoProxyCreatorIfNecessary:
public static void registerAspectJAutoProxyCreatorIfNecessary( ParserContext parserContext, Element sourceElement) {
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAutoProxyCreatorIfNecessary( parserContext.getRegistry(), parserContext.extractSource(sourceElement)); useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement); registerComponentIfNecessary(beanDefinition, parserContext); }
进入org.springframework.aop.config.AopConfigUtils#registerAspectJAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object):
@Nullable public static BeanDefinition registerAspectJAutoProxyCreatorIfNecessary( BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AspectJAwareAdvisorAutoProxyCreator.class, registry, source); }
进入org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired:
@Nullable private static BeanDefinition registerOrEscalateApcAsRequired( Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME); if (!cls.getName().equals(apcDefinition.getBeanClassName())) { int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName()); int requiredPriority = findPriorityForClass(cls); if (currentPriority < requiredPriority) { apcDefinition.setBeanClassName(cls.getName()); } } return null; }
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); beanDefinition.setSource(source); beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition); return beanDefinition; }
可以发现在加载名字叫AUTOPROXYCREATORBEANNAME的bean时会先判断该名称的bean是否存在。
我们在这里打断点: 第一个进入的是class org.springframework.aop.framework.autoproxy.InfrastructureAdvisorAutoProxyCreator:
会进入register的逻辑。
第二个进入的是class org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator:
最后注册的其实是AnnotationAwareAspectJAutoProxyCreator。
关于优先级的算法: 在AopConfigUtils初始化时会加载:
public abstract class AopConfigUtils {
/** * The bean name of the internally managed auto-proxy creator. */ public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
/** * Stores the auto proxy creator classes in escalation order. */ private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
static { // Set up the escalation list... APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class); APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class); APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class); }
计算方式:
注意,这几个ProxyCreator也属于BeanPostProcessor,是spring的拓展点。
这时我们再回过头去看org.springframework.context.annotation.AspectJAutoProxyRegistrar#registerBeanDefinitions:
它会读取org.springframework.boot.autoconfigure.aop.AopAutoConfiguration中的配置信息。
注意,针对AnnotationAwareAspectJAutoProxyCreator这个BeanPostProcessor它的aop.proxy-target-class是这样配置的,其他的processor的aop proxy则是根据自己的加载配置而定的。
关于BeanPostProcessor:
接下来我们看一看org.springframework.context.support.AbstractApplicationContext#refresh方法:
// Prepare this context for refreshing. prepareRefresh();
// Tell the subclass to refresh the internal bean factory. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context. prepareBeanFactory(beanFactory);
try { // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context. invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory);
// Initialize message source for this context. initMessageSource();
// Initialize event multicaster for this context. initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses. onRefresh();
// Check for listener beans and register them. registerListeners();
// Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event. finishRefresh(); } ...
在这里进行invokeBeanFactoryPostProcessors和registerBeanPostProcessors,在org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, java.util.List<org.springframework.beans.factory.config.beanfactorypostprocessor style="box-sizing: border-box;">)方法里会 调用org.springframework.context.support.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors(java.util.Collection, org.springframework.beans.factory.config.ConfigurableListableBeanFactory):</org.springframework.beans.factory.config.beanfactorypostprocessor>
private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } }
在这个方法里会对每个postProcessor调用postProcessBeanFactory方法。我们看一下beanPostProcessor的实现:
可以看到其中有很多PropertyResourceProcessor如com.ulisesbocchio.jasyptspringboot.configuration.EnableEncryptablePropertiesBeanFactoryPostProcessor,用于加载配置文件的。
在org.springframework.aop.framework.ProxyConfig#setProxyTargetClass方法上打断点,在debugger界面往上查找方法,会发现有很多次进入该方法(现简单例举几例):
用于给interface com.ulisesbocchio.jasyptspringboot.EncryptablePropertySource生成代理的。
然后,AopConfig方法结束了,进入org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy方法:断点可以发现service bean实例化时用的是true:
这里使用的proxyFactory是org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 1 advisors [org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor: advice org.springframework.transaction.interceptor.TransactionInterceptor@7049022f];
@Override public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException { if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) { Class<?> targetClass = config.getTargetClass(); if (targetClass == null) { throw new AopConfigException("TargetSource cannot determine target class: " + "Either an interface or a target is required for proxy creation."); } if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) { return new JdkDynamicAopProxy(config); } return new ObjenesisCglibAopProxy(config); } else { return new JdkDynamicAopProxy(config); } }
基于上面的,我们再来捋一遍:
这里用的是processor是org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator,它的proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false
@Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (this.earlyProxyReferences.remove(cacheKey) != bean) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
5.org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary:
6.org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
7.org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)
8.org.springframework.aop.framework.ProxyCreatorSupport#createAopProxy
9.org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
可以看出,最终影响DefaultAopProxyFactory中的config.getTargetClass()的是AnnotationAwareAspectJAutoProxyCreator中proxy target class的配置。最终决定是生成ObjenesisCglibAopProxy还是JdkDynamicAopProxy。