zoukankan      html  css  js  c++  java
  • 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;
        }
    }

     

  • 相关阅读:
    & 【04】 Spring中Xml属性配置的解析过程
    设计模式之模板方法设计模式
    MySQL高性能索引创建策略
    oracle用户创建及权限设置
    【已解决】关于SQL2008 “不允许保存更改。您所做的更改要求删除并重新创建以下表。您对无法重新创建的标进行了更改或者启用了‘阻止保存要求重新创建表的更改’” 解决方案
    ObjectStateManager 不包含具有对“Model”类型的对象的引用的 ObjectStateEntry
    【推荐活动】脚本娃娃同城会——上海站(20130112)
    【原创】对于访问IIS元数据库失败的解决(续)
    【原创】win7 plsql里查询出来的中文信息,复制粘贴的时候出现乱码(以前从没遇到过,第一次啊)
    oracle删除用户命令和部分命令
  • 原文地址:https://www.cnblogs.com/chenxingyang/p/15559349.html
Copyright © 2011-2022 走看看