25.5. 元数据和Spring AOP自动代理

元数据属性最有用的就是与Spring AOP联合使用。这提供了一个类似.NET的编程模型:声明式服务会自动提供给声明了元数据的属性。 这些元数据属性可以被框架支持,比如声明式事务管理,同时也能定制。

25.5.1. 基本原理

基于Spring AOP的自动代理功能,配置可能如下所示:

<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"/>

<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
  <property name="transactionInterceptor" ref="txInterceptor" />
</bean>

<bean id="txInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor">
  <property name="transactionManager" ref="transactionManager" />
  <property name="transactionAttributeSource">
    <bean class="org.springframework.transaction.interceptor.AttributesTransactionAttributeSource">
      <property name="attributes" ref="attributes" />
    </bean>
  </property>
</bean>

<bean id="attributes" class="org.springframework.metadata.commons.CommonsAttributes" />

这里的基本原理与AOP章节关于自动代理的讨论类似。

最重要的bean定义是自动代理的creator和advisor。注意实际的bean名称并不重要,重要的是它们的类。

org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator 的bean定义会根据匹配advisor实现来自动通知("auto-proxy")当前工厂中的所有bean实例。 这个类对属性一无所知,只是依赖于advisor匹配的切入点,而切入点了解这些属性。

因此我们只需要一个能提供基于属性的声明式事务管理的AOP advisor。

这样还能添加自定义的advisor实现,它们能被自动运算并应用。 (如果有必要,你也可以使用这样的advisor,它的切入点还能匹配那些相同自动代理配置中除属性以外的条件。)

最后,属性bean是Commons Attributes中的Attributes的实现。 把它替换为其它的org.springframework.metadata.Attributes接口实现,就可以从另外的源获得属性了。

25.5.2. 声明式事务管理

源码级属性的常见应用就是提供声明式事务管理。一旦有了前面的bean定义,你就可以定义任意多的需要声明式事务的应用程序对象。 只有定义了事务属性的类或者方法会被赋予事务通知。你唯一要做的就是定义需要的事务属性。

请注意你可以在类或方法级别指定事务属性。如果指定了类级别的属性,它将会被所有方法“继承”。 方法级属性则会整体覆盖任意的类级别属性。