• SpringAOP[7]基础的自动代理(AnnotationAwareAspectJAutoProxyCreator)


    原文:SpringAOP联盟(7)-基础的自动代理(AnnotationAwareAspectJAutoProxyCreator) - 简书 (jianshu.com)

     

    DefaultAdvisorAutoProxyCreatorAspectJAwareAdvisorAutoProxyCreator均实现了AbstractAdvisorAutoProxyCreator接口。

    自动代理实现的核心:在Spring容器中,bean找到“合格”Advisor。

    在上文中可知,寻找Bean上“合格”的Advisors是AbstractAutoProxyCreator定义的抽象getAdvicesAndAdvisorsForBean方法。具体逻辑由子类实现。

    而真正实现被代理类增强器解耦的自动代理器,实际上是AbstractAdvisorAutoProxyCreator去完成的。

    AbstractAdvisorAutoProxyCreator寻找“合格”Advisor,那么它眼中的合格是什么样子的呢?

    1. 子类是否允许:子类可实现isEligibleAdvisorBean(beanName)方法,对Spring容器中所有的Advisor类进行初次筛选。
    2. Advisor是否切入了Bean:每个Advisor(增强器)会根据Pointcut(切点)使用ClassFilter判断被代理类是否满足规则;使用MethodMatcher判断被代理类是否有方法满足规则;

    当然在获得Bean上合格的Advisors后,Spring允许子类进行扩展排序

     

    InfrastructureAdvisorAutoProxyCreator——基建的自动生成器


    测试方法

    @Slf4j
    public class TService {
        public void run1() {
            System.out.println("This is a run1() Method!");
        }
        @Transactional
        public void say() {
            log.info("说话...");
        }
    }
    @Configuration
    @EnableTransactionManagement//注册了ProxyTransactionManagementConfiguration
    public class MyConfig {
        @Bean("tService")
        public TService tService() {
            return new TService();
        }
    }
    public class TestSpringProxy {
        public static void main(String[] args) {
            AnnotationConfigApplicationContext applicationContext =
                    new AnnotationConfigApplicationContext(MyConfig.class);
            //可以使用@Primary指定元素,或直接使用name名获取。
            TService bean = (TService)applicationContext.getBean("tService");
            bean.say();
        }
    }

    源码分析

     

    InfrastructureAdvisorAutoProxyCreator实现了isEligibleAdvisorBean(beanName)方法,即检索出Spring中符合“要求”所有的Advisor
    public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
        @Nullable
        private ConfigurableListableBeanFactory beanFactory;
        @Override
        protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
            super.initBeanFactory(beanFactory);
            this.beanFactory = beanFactory;
        }
        //在Spring容器中获取Advisor的Bean,然后判断是否是内部的bean对象。
        @Override
        protected boolean isEligibleAdvisorBean(String beanName) {
            return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
                    this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
        }
    }

     

    而实际上,事务的Advisor和Advice均由Spring完成注册。
    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
        //注册了Advisor
        @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)  //声明的role为基础类(Spring内部使用的类)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
            BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor());
            if (this.enableTx != null) {
                advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            }
            return advisor;
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
        //注册了Advice
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionInterceptor transactionInterceptor() {
            TransactionInterceptor interceptor = new TransactionInterceptor();
            interceptor.setTransactionAttributeSource(transactionAttributeSource());
            if (this.txManager != null) {
                interceptor.setTransactionManager(this.txManager);
            }
            return interceptor;
        }
    }

     

  • 相关阅读:
    AcWing 852. spfa判断负环 边权可能为负数。
    面试题 02.01. 移除重复节点
    1114. 按序打印
    剑指 Offer 38. 字符串的排列
    557. 反转字符串中的单词 III
    645. 错误的集合
    面试题 05.03. 翻转数位
    1356. 根据数字二进制下 1 的数目排序
    748. 最短完整词
    剑指 Offer 32
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/15559349.html
Copyright © 2020-2023  润新知