前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >spring源码之aop proxy

spring源码之aop proxy

作者头像
山行AI
发布2019-08-05 20:54:38
6300
发布2019-08-05 20:54:38
举报
文章被收录于专栏:山行AI山行AI

从入口分析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);    }
}

AnnotationAwareAspectJAutoProxyCreator的加载及aop-proxy-target-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

关于BeanPostProcessor:

  • https://www.iteye.com/topic/1122859
  • https://jinnianshilongnian.iteye.com/blog/1492424

接下来我们看一看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界面往上查找方法,会发现有很多次进入该方法(现简单例举几例):

  1. jasypt置为true:

用于给interface com.ulisesbocchio.jasyptspringboot.EncryptablePropertySource生成代理的。

  1. spring-context的ProxyAsyncConfiguration,置为false:
  1. org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration#methodValidationPostProcessor:
  1. org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration#persistenceExceptionTranslationPostProcessor:

然后,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);        }    }

整体流程

基于上面的,我们再来捋一遍:

  1. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean:
  1. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition):
  1. org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization:

这里用的是processor是org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator,它的proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false

  1. org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization:
@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。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-08-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 开发架构二三事 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • AnnotationAwareAspectJAutoProxyCreator的加载及aop-proxy-target-class的配置
  • 其它BeanPostProcessor
  • 整体流程
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档