美文网首页Spring
Spring |3.1.x 下

Spring |3.1.x 下

作者: 不一样的卡梅利多 | 来源:发表于2020-05-21 12:19 被阅读0次

    上节简单介绍了3.1.x 版本较以前版本变化之处,以及如何解析注解。这节详细介绍下注解的整个处理流程。

    客户端入口代码

    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
            context.scan(AnnotationContextTest.class.getPackage().getName());
            context.refresh();
            for (String beanDefinitionName : context.getBeanDefinitionNames()) {
                System.out.println(beanDefinitionName);
            }
    

    1、new AnnotationConfigApplicationContext

    public AnnotationConfigApplicationContext() {
           this.reader = new AnnotatedBeanDefinitionReader(this);
           this.scanner = new ClassPathBeanDefinitionScanner(this);
       }
    

    先调用父类构造函数:
    AnnotationConfigApplicationContext 对bean 操作委派给DefaultListableBeanFactory 处理

    public GenericApplicationContext() {
            this.beanFactory = new DefaultListableBeanFactory();
        }
    

    1.1.1 registerAnnotationConfigProcessors

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
            Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
            Assert.notNull(environment, "Environment must not be null");
            this.registry = registry;
            this.environment = environment;
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
        }
    

    1、注册系统默认的注解处理器 比如 :ConfigurationClassPostProcessor, @Configuration 注解核心处理类

    注解解析流程
    1、ClassPathBeanDefinitionScanner 扫描包下面的被注解@Component 的类
    以及被 @Component 注解的注解@Repository,@Controller ,@Service,
    @Configuration,这些注解的类,除了是配置bean 外也是一个普通的BeaDefiniton。

    @Repository,@Controller ,@Service @Configuration,@Component 这类注解被叫做元注解

    2、ConfigurationClassPostProcessor 会解析@Configuration注解,然后将解析的结果注册到BeanDefinitionRegister 上面。这部分解析会使用其他注解来进行扩展,去找到更多的BeanDefinition。
    1、 @Profile ,
    2、@PropertySource
    3、@ComponentScan :类扫描注解
    4、@ImportResource :资源导入注解
    5、@Bean :bean定义 注解
    6、@Import :导入其他类定义的注解

    这些注解都要联合@Configuration 注解才能生效。@Configuration 注解解析核心方法为:ConfigurationClassParser#processConfigurationClass,会递归解析父类的注解。

    3、扩展注解 @Import 解析流程

    private void processImport(ConfigurationClass configClass, String[] classesToImport, boolean checkForCircularImports) throws IOException {
            if (checkForCircularImports && this.importStack.contains(configClass)) {
                this.problemReporter.error(new CircularImportProblem(configClass, this.importStack, configClass.getMetadata()));
            }
            else {
                this.importStack.push(configClass);
                AnnotationMetadata importingClassMetadata = configClass.getMetadata();
                for (String candidate : classesToImport) {
                    MetadataReader reader = this.metadataReaderFactory.getMetadataReader(candidate);
                    if (new AssignableTypeFilter(ImportSelector.class).match(reader, this.metadataReaderFactory)) {
                        // the candidate class is an ImportSelector -> delegate to it to determine imports
                        try {
                            ImportSelector selector = BeanUtils.instantiateClass(
                                    this.resourceLoader.getClassLoader().loadClass(candidate), ImportSelector.class);
                            processImport(configClass, selector.selectImports(importingClassMetadata), false);
                        }
                        catch (ClassNotFoundException ex) {
                            throw new IllegalStateException(ex);
                        }
                    }
                    else if (new AssignableTypeFilter(ImportBeanDefinitionRegistrar.class).match(reader, metadataReaderFactory)) {
                        // the candidate class is an ImportBeanDefinitionRegistrar -> delegate to it to register additional bean definitions
                        try {
                            ImportBeanDefinitionRegistrar registrar = BeanUtils.instantiateClass(
                                    this.resourceLoader.getClassLoader().loadClass(candidate), ImportBeanDefinitionRegistrar.class);
                            registrar.registerBeanDefinitions(importingClassMetadata, registry);
                        }
                        catch (ClassNotFoundException ex) {
                            throw new IllegalStateException(ex);
                        }
                    }
                    else {
                        // the candidate class not an ImportSelector or ImportBeanDefinitionRegistrar -> process it as a @Configuration class
                        this.importStack.registerImport(importingClassMetadata.getClassName(), candidate);
                        processConfigurationClass(new ConfigurationClass(reader, true));
                    }
                }
                this.importStack.pop();
            }
        }
    

    ImportSelector 返回类定义的配置类名称,这样就可以实现灵活扩展
    ImportBeanDefinitionRegistrar :灵活注册bean。

    @import使用:

    @import(ImportSelector.class) 
    @import(ImportBeanDefinitionRegistrar.class)
    

    @EnableTransactionManagement 实现分析

    注解定义:

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Import(TransactionManagementConfigurationSelector.class)
    public @interface EnableTransactionManagement {}
    

    ImportSelector 返回扩展的类配置名称,ConfigurationClassParser#processImport 对返回的类,进行配置解析,并且注册bean信息。

    public class TransactionManagementConfigurationSelector
            extends AdviceModeImportSelector<EnableTransactionManagement> {
    
        /**
         * {@inheritDoc}
         * @return {@link ProxyTransactionManagementConfiguration} or
         * {@code AspectJTransactionManagementConfiguration} for {@code PROXY} and
         * {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()}, respectively
         */
        @Override
        protected String[] selectImports(AdviceMode adviceMode) {
            switch (adviceMode) {
                case PROXY:
                    return new String[] { AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName() };
                case ASPECTJ:
                    return new String[] { TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME };
                default:
                    return null;
            }
        }
    
    
    }
    

    如果配置为 :PROXY
    返回
    1、AutoProxyRegistrar 注册代理类

    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
    

    2、ProxyTransactionManagementConfiguration 被@Configuration 注解 生成事务管理相关的配置信息。

    @Configuration
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
        @Bean(name=TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
            BeanFactoryTransactionAttributeSourceAdvisor advisor =
                new BeanFactoryTransactionAttributeSourceAdvisor();
            advisor.setTransactionAttributeSource(transactionAttributeSource());
            advisor.setAdvice(transactionInterceptor());
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
            return advisor;
        }
    
        @Bean
        @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
        public TransactionAttributeSource transactionAttributeSource() {
            return new AnnotationTransactionAttributeSource();
        }
    
        @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;
        }
    
    }
    

    小结:

    注解配置的主要流程为 :
    1、ClassPathBeanDefinitionScanner#scan(package) 扫描包下面的被注解@Component 的类以及被 @Component 注解的注解@Repository,@Controller ,@Service, @Configuration 的类

    2、ConfigurationClassParser#processConfigurationClass 对注解了@Configuration 的类进行解析, 二次扩展注册bean。

    3、其他流程在见AbstractApplicationContext#refresh 方法

    Spring 专题

    相关文章

      网友评论

        本文标题:Spring |3.1.x 下

        本文链接:https://www.haomeiwen.com/subject/yhczohtx.html