第 25 章 注解和源代码级的元数据支持

目录

25.1. 简介
25.2. Spring的元数据支持
25.3. 注解
25.3.1. @Required
25.3.2. Spring中的其它@Annotations
25.4. Jakarta Commons Attributes集成
25.5. 元数据和Spring AOP自动代理
25.5.1. 基本原理
25.5.2. 声明式事务管理

25.1. 简介

源代码级的元数据通常是对类或方法这样的程序元素的属性注解的补充。

举例来说,我们可以象下面这样给一个类添加元数据:

/**
 * Normal comments here
 * @@org.springframework.transaction.interceptor.DefaultTransactionAttribute()
 */
public class PetStoreImpl implements PetStoreFacade, OrderService {

我们也可以像下面这样为一个方法添加元数据:

/**
 * Normal comments here
 * @@org.springframework.transaction.interceptor.RuleBasedTransactionAttribute()
 * @@org.springframework.transaction.interceptor.RollbackRuleAttribute(Exception.class)
 * @@org.springframework.transaction.interceptor.NoRollbackRuleAttribute("ServletException")
 */
public void echoException(Exception ex) throws Exception {
    ....
}

这两个例子都使用了Jakarta Commons Attributes的语法。

源代码级的元数据随着XDoclet(在Java世界中)和Microsoft的.NET平台的发布被引入主流, 后者使用了源代码级的属性来控制事务、缓冲池(pooling)和一些其他的行为。

J2EE社区已经认识到了这种方法的价值。举例来说,跟EJB中专用的传统XML部署描述文件比起来它要简单很多。 与人们乐意做的把一些东西从程序源代码中提取出来的做法相反,一些重要的企业级设置 - 特别是事务特性 - 应该属于程序代码。 并不像EJB规范中设想的那样,调整一个方法的事务特性基本没有什么意义(尽管像事务超时这样的参数可能改变)。

虽然元数据属性主要用于框架的基础设施中,来描述应用程序的类所需要的服务,但是它也可以在运行时被查询。 这是它与XDoclet这样的解决方案的关键区别,XDoclet主要把元数据作为生成代码的一种方式,比如生成EJB类。

下面有几种解决方案,包括:

  • 标准Java注解:标准Java元数据实现(作为JSR-175标准被开发并可在 Java 5中找到)。 Spring已经在事务划分、JMX和切面(准确地说它们是AspectJ的注解)中支持Java 5注解。 不过, 既然Spring也支持Java 1.4,我们仍需要一个JVM不同版本间的解决方案。Spring元数据支持就提供了这样一个方案。

  • XDoclet:成熟的解决方案,主要用于代码生成。

  • 在多种不同的针对Java 1.4的开源属性实现中,Commons Attributes看起来是最完整的实现。 所有的这些实现都需要一个特定的前置编译或后置编译的步骤。