Spring中tx命名空间和配置注解工作原理浅析

本文来自转载,供后期方便回顾。

在使用Spring时,对于一些功能的配置可以通过Spring提供的XML命名空间进行配置,也可以通过提供的注解进行配置。这两种方式都是等价的,它们背后对应的工作原理是什么呢?

以事务管理为例:(以下代码来自Spring的API文档)

@EnableTransactionManagement注解启用了事务管理功能。

@Configuration  
@EnableTransactionManagement  
 public class AppConfig {  
     @Bean  
     public FooRepository fooRepository() {  
         // configure and return a class having @Transactional methods  
         return new JdbcFooRepository(dataSource());  
     }  

     @Bean  
     public DataSource dataSource() {  
         // configure and return the necessary JDBC DataSource  
     }  

     @Bean  
     public PlatformTransactionManager txManager() {  
         return new DataSourceTransactionManager(dataSource());  
     }  
 }  

上面的代码与以下的XML配置是等效的

<beans>  
     <tx:annotation-driven/>  
     <bean id="fooRepository" class="com.foo.JdbcFooRepository">  
         <constructor-arg ref="dataSource"/>  
     </bean>  
     <bean id="dataSource" class="com.vendor.VendorDataSource"/>  
     <bean id="transactionManager" class="org.sfwk...DataSourceTransactionManager">  
         <constructor-arg ref="dataSource"/>  
     </bean>  
 </beans>  

一、XML配置工作机制

类似于“<tx:annotation-driven/>”的配置是如何生效的呢?以启动ClassPathXmlApplicationContext为例。

装载Bean部分过程如下:
  1. ClassPathXmlApplicationContex构造函数中自动调用refresh()完成Bean信息的装载(除非显示指定,手工刷新):

  2. ApplicationContext通过XmlBeanDefinitionReader来读取和解析XML文件。

  3. XmlBeanDefinitionReader通过DefaultBeanDefinitionDocumentReader来读取XML中定义的Bean信息,并保存到BeanDefinitionRegistry中。

  4. 对于默认命名空间中的XML标签通过parseDefaultElement()来进行解析。支持的XML标签有:import、alias、bean和beans,其他标签都会被忽略。

  5. 对于其他命名空间中的标签,使用DefaultNamespaceHandlerResolver来获取对应的NamespaceHandler,完成标签的解析。NamespaceHandler相关的配置信息放在Spring的jar包中的” META-INF/spring.handlers”路径下。

由此可见,当XML中存在“<tx:annotation-driven/>”时,命名空间为tx,从配置文件中查找到的NamespaceHandler为TxNamespaceHandler。由TxNamespaceHandler负责具体的解析工作,它的部分代码如下

public void init() {  
  registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());  
  registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());  
  registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());  
}  

由代码可见,tx命名空间只支持”advice”、”annotation-driven”和"jta-transaction-manager"三个Bean定义。

二、注解配置的工作原理

@EnableTransactionManagement注解又是如何起作用的呢?

  1. ApplicationContex调用refresh()中,首先刷新BeanFactory完成PostProcessor监听器的注册,其中就有ConfigurationClassPostProcessor,用来解析与@Configuration注解同时出现的注解信息。

  2. 调用所有的BeanFactoryPostProcessor,其中ConfigurationClassPostProcessor对BeanFactory中所有的bean定义进行检查,对标注了@Configuration的Bean使用ConfigurationClassParser进行解析。

  3. Parser解析包括:
    1)对Member成员的递归解析;
    2)检查Bean定义中的注解:@PropertySourc、@ComponentScan、@Import、@ImportResource、@Bean,以及对超类进行检查。记录相关的注解信息。

  4. 在生成Bean实例前,调用相关的BeanPostProcessor,其中一步处理是为Bean找到相关的Advisor,完成切面的“编织”工作

转载于:https://blog.51cto.com/dengshuangfu/2396801

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值