领先一步
VMware 提供培训和认证,助您加速进步。
了解更多几位用户询问我们是否致力于 Spring Java 配置,以及它与 Spring 2.5 中引入的 注解配置选项 的关系。答案是肯定的,我们致力于 Java 配置;这两种方法并非互斥。
这两种配置方法截然不同:Spring 框架中的 @Autowired 注解通过业务对象中的注解来配置组件,而 Spring Java Config 则采用一种独特的方法,将注解外部化到专用的配置类中。这两种方法没有绝对的对错之分,在不同的场景下都有其优势。甚至可以在同一个应用程序中同时使用这两种方法。
如果您认为 Spring 就等于 XML,那么是时候重新思考了。(无论如何,这从未完全准确过,因为 Spring 核心容器一直使用自己的 Java 元数据,并不了解 XML 或任何其他表示形式。)
这让我们想起了一个重要的哲学原则:我们使用 Spring 的使命是为企业 Java 提供最佳的组件模型,设定灵活性的标准以满足复杂的需求,并为现实世界的问题提供全面的解决方案。我们不认为存在适用于所有情况的单一配置模型,我们相信在强大的、可扩展的模型内提供选择。无论您选择如何定义您的 Spring 管理的对象,它们都可以获得相同的丰富企业服务、无与伦比的第三方集成、真正的 AOP、许多扩展点等。
因此,Spring 2.5 的 @Component 和 @Autowired 注解(让容器自动检测 Spring 管理的对象)可以与 Java Configuration、XML 和其他配置选项愉快地共存。
这让我想起:本周晚些时候,我将在 旧金山 QCon 大会 上讨论 Spring 容器的配置方式,届时可以收集反馈,这应该会很有趣。之后,我会尝试在这里或 SpringFramework.org 上发布幻灯片。
由于 Costin 致力于 Spring Dynamic Modules for OSGi,Spring Java Config 一度进展缓慢,但现在已步入正轨。在过去的几天里,我为此做了不少工作:将其更新到 Spring 2.5;移除未使用的代码;并添加了一个备受期待的新功能——配置值(以及 Bean)的外部化。
虽然 M2 版本在 2.5RC1 上运行良好(考虑到 JavaConfig 对 Spring IoC 的深度使用,这足以证明 2.5 的向后兼容性),但它包含了自己的注解扫描代码(Spring 框架采纳并进一步发展了它),因此迁移到较新的 Spring 版本是明智的。
新的配置属性外部化功能采用了 JIRA 中关于使用抽象方法(感谢 Guillaume Duchesneau)的建议。
这些方法使用了新的 @ExternalValue 注解进行注解,如下所示:
@Configuration @ResourceBundles("classpath:/com/yourcompany/yourpackage/basename") static abstract class ConfigurationExample {@Bean
public Person john() {
Person john= new Person();
john.setName(getName());
john.setAge(methodWithArbitraryNameReturningAge());
john.setBusy(busy());
return john;
}
// Property name defaults to method name.
// In the case of a getter method, it's the property name--
// "name" in this case
@ExternalValue
public abstract String getName();
// Property name is taken from annotation value
@ExternalValue("age")
public abstract int methodWithArbitraryNameReturningAge();
@ExternalValue
protected abstract boolean busy();
}
Spring Java Config 会继承这些类,来实现这些方法,以便在运行时返回外部化属性。(它还会因为其他原因继承配置类,例如缓存单例 Bean 方法的返回值。)这些方法可以是 public 或 protected。
配置类上的 @ResourceBundles 注解标识了一个或多个要用于解析值的资源束,这些值可以通过方法名或注解上的显式字符串值来指定。这些位置是 Spring 资源位置字符串。
带有 @ExternalBean 注解的方法可以是具体的,在这种情况下,如果找不到外部值,则会使用实际的返回值,如下所示: @ExternalValue public int otherNumber() { return 25; } 这种用法意味着该值是可外部化的,但外部化是可选的,就像具有可用默认值的 Bean 属性一样。
正如您所料,示例的属性文件如下所示:
name=John Doe age=45 busy=false
底层机制被设计为可扩展的,因此属性文件不是唯一的选项,我们将在未来的版本中提供其他选项。抽象方法的方式允许动态获取值:例如,从数据库中获取,或者自定义地从另一个系统中获取。
目前,该示例仅在 SVN 中可用,但我们计划在本月发布 M3 版本。未来,位于西雅图的 Interface21 顾问 Chris Beams 将负责该项目。在 Interface21,我们相信我们所有的技术人员都应该参与到我们作为一家公司所做的一切:产品开发、咨询和培训。产品开发人员会提供一些培训和咨询;服务交付人员会参与项目。这确保了每个人都能为我们共同关心的开源项目做出贡献,并且每个人都能扎根于真实的业务需求,而不是(J2EE 过去存在的)与世隔绝地开发基础设施。Chris 主要从事咨询和培训,但他将“对齐”Spring Java Config,使其成为他的主要开发重点,因此他将投入大量时间进行开发,并得到 Costin 和我的帮助。
Spring Java Config 何时能达到 1.0 最终版,部分取决于您。我们需要在实际使用中的反馈;我们需要功能请求(尽管我们可能希望在 1.0 版本中保持范围的可管理性);我们需要在优先级排序方面的帮助。如果您想要这些,请告诉我们,我们会倾听!