领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多这是关于“Spring 3 简化”系列文章的第二篇,昨天由Keith开始,我想对 Spring 的新@Configuration注解和相关支持做一个非常简短且实用的介绍。
正如关注 Spring JavaConfig 项目的人所知,一个带有 @Configuration 注解的类与 Spring XML 文件的作用非常相似。它提供了一种以代码为中心的方式来声明 Spring bean 定义,而只需使用方法和注解。你可以称之为普通旧配置 :) 这意味着对于简单的场景,不需要 XML!
让我们开始吧。为了演示 @Configuration 功能,我在新的 spring-samples SVN 存储库中创建了一个非常简单的项目。您可能想立即同步并构建它。您需要一个 Subversion 客户端和最近版本的 Maven。
svn co https://src.springframework.org/svn/spring-samples/configuration-basic/trunk configuration-basic cd configuration-basic mvn clean test [...] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESSFUL [INFO] ------------------------------------------------------------------------
Eclipse 的 .classpath 和 .project 元数据也包含在检出中,因此您可以使用SpringSource Tool Suite或任何最近版本的 Eclipse(安装了m2eclipse 插件)导入项目。在这两种情况下,都使用文件->导入->将现有项目导入工作区。
首先,让我们看一下AppConfig.java。这个带有 @Configuration 注解的类与基于 XML 的 Spring 应用中的 app-config.xml 文件的作用相同。在查看项目时,这是一个很好的起点,因为它充当对象实例在运行时如何连接和管理的“蓝图”。
@Configuration
public class AppConfig {
public @Bean TransferService transferService() {
return new TransferServiceImpl(accountRepository());
}
public @Bean AccountRepository accountRepository() {
return new InMemoryAccountRepository();
}
}
当然,这是一个简单的应用程序示例,甚至连真正的 JDBC DataSource 都没有包含在内。没关系,这篇文章的目标只是传达基本概念。上面的 @Bean 方法将在正确的时间被 Spring 容器识别并调用,返回的对象将在 Spring 容器中像其他任何 bean 一样被管理。您可以看到,bean 之间的依赖关系可以简单地表达为从一个 bean 方法到另一个 bean 方法的调用。TransferServiceImpl 需要一个 AccountRepository 构造函数参数,因此只需调用 accountRepository() 方法。
精通 Spring 的用户会看到这种情况,并提出问题“bean 的作用域呢?”这是一个好问题。如您所知,所有 Spring bean 都有一个作用域。默认情况下,bean 的作用域是“单例”,这意味着每个 Spring 容器只有一个该 bean 的实例。浏览上面的代码,似乎如果我们多次调用 accountRepository(),实际上会创建多个实例,但事实并非如此!当 @Configuration 类在运行时被处理时,它会被动态地子类化(使用 CGLIB),并且 @Bean 方法的子类实现会被增强以确保作用域语义得到尊重。
如您所见,定义 @Bean 方法非常简单。现在,让我们引导容器并使用这些对象。
看一下TransferServiceTest JUnit 系统测试及其 transfer100Dollars() @Test 方法。您首先会注意到使用了AnnotationConfigApplicationContext。这个新的 ApplicationContext 实现已在 Spring 3 中添加,以支持直接使用 @Configuration 类实例化 Spring 容器。上下文使用 AppConfig.class 作为构造函数参数创建,之后我们使用getBean(Class
public class TransferServiceTest {
@Test
public void transfer100Dollars() {
// create the spring container using the AppConfig @Configuration class
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
// retrieve the beans we'll use during testing
AccountRepository accountRepository = ctx.getBean(AccountRepository.class);
TransferService transferService = ctx.getBean(TransferService.class);
// create accounts to test against
accountRepository.add(new Account("A123", 1000.00));
accountRepository.add(new Account("C456", 0.00));
// check account balances before transfer
assertThat(accountRepository.findById("A123").getBalance(), equalTo(1000.00));
assertThat(accountRepository.findById("C456").getBalance(), equalTo(0.00));
// perform transfer
transferService.transfer(100.00, "A123", "C456");
// check account balances after transfer
assertThat(accountRepository.findById("A123").getBalance(), equalTo(900.00));
assertThat(accountRepository.findById("C456").getBalance(), equalTo(100.00));
}
}
就是这样!简单、纯 Java、类型安全的配置。我们希望您会发现这是 Spring 核心依赖注入支持的一个方便且强大的补充。
当然,我们今天只是触及了表面。@Configuration 类可以做更多的事情,我们将在以后的文章中探讨这些功能。但不要等我 - 您现在就可以自己查看所有这些功能,方法是阅读Spring 3 参考文档中的 @Configuration 部分。我鼓励大家使用此示例项目作为起点,您可以从中快速路测此新支持的其余部分。
期待您的反馈。享受使用 @Configuration 和所有新的 Spring 3 功能,并祝您假期快乐!