Web Beans 中的 XML 配置

发布者:    |       CDI

Web Beans 规范 定义了一种使用 XML 命名空间的 XML 配置格式,以实现类型安全。

想象一下我们有一个以下这样的类

public class ShoppingCart {
    
    private final PaymentProcessor paymentProcessor;
    private final User customer;
    
    public ShoppingCart(PaymentProcessor paymentProcessor, User customer) { 
        this.paymentProcessor = paymentProcessor;
        customer = customer;
    }

    ...

}

当然,我们可以使用注解来配置其作用域、名称和依赖关系

@SessionScoped
@Named("cart")
public class ShoppingCart {
    
    private final PaymentProcessor paymentProcessor;
    private final User customer;
    
    @Initializer
    public ShoppingCart(@PayBy(CREDIT_CARD) PaymentProcessor paymentProcessor, @LoggedIn User customer) { 
        this.paymentProcessor = paymentProcessor;
        customer = customer;
    }

    ...

}

但是假设这个类定义在一个可重用的库中,并且这个元数据依赖于它所部署的应用程序。那么在 XML 中定义元数据会更好。Web Beans 早期草案定义了一种与其它 Java EE 部署描述符相似的配置格式

<web-beans ...>

   <component>

      <class>org.example.ShoppingCart</class>
      <named>cart</named>
      <scope>javax.webbeans.SessionScoped</scope>

      <constructor>
         <param>
            <type>org.example.PaymentProcessor</type>
            <binding>org.example.PayBy(CREDIT_CARD)</binding>
         </param>
         <param>
            <type>org.example.User</type>
            <binding>org.example.LoggedIn</binding>
         </param>
      </constructor>

   </component>

</web-beans>

这种方法的几个问题如下

  • 相当冗长
  • 有趣的信息(类型名称)无法与 XML 架构进行验证
  • 有趣的信息无法在没有了解 Java 类型的特殊工具的情况下自动完成

更糟糕的是,XML 格式过分强调实际的 Java 构造(例如“构造函数”、“param”等),这对于第三方库的配置来说是不合适的。

因此,Web Beans 公开草案定义了一种不同的方法,灵感来自 Spring 2 和 Seam 2。想法是为每个 Java 包定义一个相应的 XML 命名空间。例如,以下命名空间urn:java:org.example代表 Java 包org.example。该命名空间中的 XML 元素代表该包中的类型或类型成员。

我们可以将我们的示例重写如下

<WebBeans xmlns="urn:java:javax.webbeans"
          xmlns:eg="urn:java:org.example">

   <eg:ShoppingCart>
      <Named>cart</Named>
      <SessionScoped/>
      
      <eg:PaymentProcessor>
         <eg:PayBy>CREDIT_CARD<eg:PayBy>
      </eg:PaymentProcessor>
      
      <eg:User>
         <eg:LoggedIn/>
      </eg:User>
      
   </eg:ShoppingCart>
   
</WebBeans>

现在,这种方法的真正美妙之处在于我们可以为每个命名空间编写一个 XML 架构,这样我们就可以在编写 XML 文档时利用自动完成和验证。更好的是,RI 项目计划创建一个 Java 6 注解处理器(一个 javac 的编译器插件)javac) 这会在编译过程中自动生成该模式。因此,每次您编译代码时,都会立即在您的XML配置中看到任何生成的错误!因此,这种方法解决了影响Java开发的主要原因之一的 XML地狱

就我个人而言,我对任何同时更具类型安全和更简洁(通常类型安全会以冗余为代价)的解决方案都感到非常着迷。然而,Web Beans EG的至少一位成员担心,类型安全的XML格式与其他Java EE部署描述符使用的格式不一致,可能会造成混淆。

因此,我想就这个问题从社区收集反馈。您更喜欢哪种风格?请在评论中告诉我们您的看法。


返回顶部