领先一步
VMware 提供培训和认证,以加快您的进度。
了解更多正如 Juergen 在昨天的文章中提到的,正如我在之前的关于 3.1 M1 的文章我的 上一篇 文章中提到的那样,Spring 3.1 的主要主题之一是完成我们在 Spring 中基于代码配置的愿景。我们认为,现代企业级 Java 应用程序应该可以选择 Java 和 XML 作为其配置的一流选项。在这篇文章中,我们将看到 Spring 3.1 M2 如何使这成为现实。
请注意,尽管自 Spring 3.0 以来一直可以使用基于 Java 的配置,但在此版本中,它现在与多年来开发的许多基于 XML 的功能相当。我们认为结果非常吸引人,在某些情况下甚至比基于 XML 的配置具有明显的优势。简而言之:如果您在 3.0 中没有考虑它,那么您现在真的应该仔细研究一下。
如果您一直密切关注,您会记得我们在 3.1 M1 中引入了FeatureSpecification
类和@Feature
方法的概念。事实证明,我们决定在 3.1 M2 中用不同的机制替换它。为什么?因为尽管FeatureSpecification
类提供了一种方便的机制来配置 Spring 容器的功能,例如注解驱动的交易管理和组件扫描,但这带来了两个缺点:缺乏可扩展性和缺乏实现透明度。我们越想越意识到我们可以做得更好。虽然FeatureSpecification
类通过流畅的 API 紧密地镜像了 XML 命名空间,但新的解决方案采用了不同的形式——一种专门设计用来利用 Java 自身优势的形式。
简而言之,我们将新的机制称为“@Enable
”注解。这些注解应用于@Configuration
类上的类型级别。让我们以@EnableTransactionManagement
为例。大多数用户都会熟悉以下 Spring XML 代码片段
<beans>
<tx:annotation-driven/>
</beans>
这当然启用了 Spring 使用@Transactional
注解对事务管理的支持。现在让我们看看代码中的等效配置
@Configuration
@EnableTransactionManagement
public class AppConfig {
// ...
}
很简单,对吧?当然还有更多内容要说,我鼓励大家查看我们在本版本中提供的@Enable
注解的Javadoc。您会发现它们包含大量上下文、示例和对重要相关类型的引用。它应该包含您入门所需的一切。当然,我们还将在 3.1 GA 之前更新参考文档,但我们跳过了 M2 的这一步,因为 Javadoc 已经得到了很多改进。
还要查看@Configuration
的Javadoc,它在 M2 中进行了大量修改,以展示与其他注解和机制(如新的Environment
抽象)的主要集成。
关于@EnableWebMvc
注解,这是一个基于 Java 的配置证明比 XML 命名空间替代方案具有真正优势的绝佳示例。Rossen 将在本系列的后续文章中详细介绍此主题,敬请关注。
Spring 对 Hibernate 的支持一直是该框架更受欢迎的功能之一,它始终通过 XML 进行配置。在 M2 中,我们引入了SessionFactoryBuilder
和AnnotationSessionFactoryBuilder
API,这使得基于代码的 Hibernate SessionFactory
配置变得轻而易举。请查看
@Configuration
public class DataConfig {
@Bean
public SessionFactory sessionFactory() {
return new AnnotationSessionFactoryBuilder()
.setDataSource(dataSource())
.setPackagesToScan("com.myco")
.buildSessionFactory();
}
}
请参阅 Javadoc 以了解更多示例和具体细节
使用 JPA 的 Spring 用户会熟悉我们的LocalContainerEntityManagerFactoryBean
。我们添加了一个“packagesToScan
”属性,允许您完全放弃 persistence.xml!顺便说一句,这与 Spring 的 Hibernate AnnotationSessionFactoryBean
上同名属性非常相似。这是一个示例
@Configuration
public class DataConfig {
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean emf =
new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource())
emf.setPackagesToScan("com.myco")
return emf;
}
}
Servlet 3.0 引入了一些非常有趣的新功能,用于基于代码的 servlet 容器配置。本质上,ServletContext
API 已得到增强,允许用户以基于类或基于实例的方式注册 servlet、过滤器和监听器。请查看
这意味着现在可以以编程方式注册面向 servlet 的组件,例如 Spring 的DispatcherServlet
和ContextLoaderListener
,而不是通过 web.xml 以声明方式注册。
唯一缺少的是引导机制——在 servlet 容器生命周期的明确点执行这些注册的地方。幸运的是,Servlet 3.0 也解决了这个问题,使用了ServletContainerInitializer
。
ServletContainerInitializer
是一个低级 SPI,主要面向 Spring 等框架使用。我将细节留给 Javadoc(以下链接),但简而言之,Spring 3.1 M2 现在提供了一个非常方便的WebApplicationInitializer
接口,它与ServletContainerInitializer
SPI 协同工作,允许您以编程方式引导 servlet 容器。这是一个快速示例
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext()
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
如您所见,DispatcherServlet
现在拥有一个接受WebApplicationContext
的构造函数。以下是 Javadoc
XmlWebApplicationContext
,但您当然也可以选择AnnotationConfigWebApplicationContext
,并通过@Configuration
类完全引导。
当spring-web
模块 JAR 存在于您的类路径中时,您的WebApplicationInitializer
实现将由 Spring 与ServletContainerInitializer
机制结合自动检测和处理。这意味着您可以根据需要准确地打包它们到您的应用程序中(再见,WEB-INF!)我们已经在 Glassfish 3.1 和 Tomcat 7.0.15 上成功测试了所有这些,所以现在是时候开始使用 Spring 3.1 和 Servlet 3.0 了。
有关完整的用法说明,请查看WebApplicationInitializer
本身的 Javadoc
有关从 web.xml 迁移到WebApplicationInitializer
的完整(且简洁)示例,请查看 Spring Greenhouse 参考应用程序的“servlet3”分支中的此提交
M1 引入了Environment
抽象和统一的PropertySource API。在 M2 中,我们的目标是使这些组件尽可能易于配置和使用。新的@PropertySource
注解允许您从@Configuration
类中为环境贡献属性源
@Configuration
@PropertySource("classpath:/com/myco/app.properties")
public class AppConfig {
@Autowired
Environment env;
@Bean
public TestBean testBean() {
TestBean testBean = new TestBean();
testBean.setName(env.getProperty("testbean.name"));
return testBean;
}
}
这与传统的PropertyPlaceholderConfigurer
(<context:property-placeholder>
)方法不同。在这里,我们将属性源贡献给环境,将环境注入到我们的@Configuration
类中,然后使用环境的#getProperty
方法系列查找所需的属性。查看@PropertySource
和Environment
的 Javadoc 以了解完整详细信息。
FactoryBeans
,再到消除 web.xml 和 persistence.xml 等非 Spring XML,我们现在可以自豪地说,Spring 的基于代码的配置在整个框架中都是一流的。唯一剩下的就是您的反馈!正如 Juergen 提到的,如果您尚未开始,现在是尝试 3.1 的时候了。我们现在正在进入候选发布阶段,这是根据您的实际使用情况进行改进的最佳时机。请让我们知道您的使用情况如何!
哦,还有一件事……如果您还没有注意到,Spring 现在在 Twitter 上了!关注@springframework 以了解最新的发行版以及来自框架本身的 Spring 相关见解。希望在那里见到您,感谢您的阅读!