我习惯使用Spring进行xml配置。使用xml,我可以为一个类提供一个主要实现和一个测试实现,这样测试实现将用于JUnit测试,如何使用注释执行此操作?因为看起来已经在" @限定符"中选择了实现。注释?
让我们举个例子:
<bean id="myService" class="example.Service" />
<bean id="myHibernateDao" class="example.HibernateDao" />
<bean id="myStubDao" class="example.StubDao" />
在xml配置中,我可以在src / main / resources中使用它:
<bean id="myService" class="example.Service">
<ref="myHibernateDao" />
</bean>
这在src / test / resources中:
<bean id="myService" class="example.Service">
<ref="myStubDao" />
</bean>
如果我已将@Qualifier(&#34; myHibernateDao&#34;)声明到我的服务类中,如何使用注释执行此操作?
答案 0 :(得分:0)
正如上面的评论和spring blog中所述,您可以通过@Profile
注释执行此操作。
请从以下示例中找到示例配置
DataConfig.java
interface DataConfig {
DataSource dataSource();
}
StandaloneDataConfig .java
@Configuration
@Profile("dev")
public class StandaloneDataConfig implements DataConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL)
.addScript("classpath:com/bank/config/sql/schema.sql")
.addScript("classpath:com/bank/config/sql/test-data.sql")
.build();
}
}
JndiDataConfig.java
@Configuration
@Profile("production")
public class JndiDataConfig implements DataConfig {
@Bean
public DataSource dataSource() {
try {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:comp/env/jdbc/datasource");
} catch (NamingException ex) {
throw new RuntimeException(ex);
}
}
}
TransferServiceConfig.java
@Configuration
public class TransferServiceConfig {
@Autowired
DataConfig dataConfig;
@Bean
public TransferService transferService() {
return new DefaultTransferService(accountRepository(), feePolicy());
}
@Bean
public AccountRepository accountRepository() {
return new JdbcAccountRepository(dataConfig.dataSource());
}
@Bean
public FeePolicy feePolicy() {
return new ZeroFeePolicy();
}
}
将bean配置文件设置为应用程序上下文
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().setDefaultProfiles("dev");
ctx.register(TransferServiceConfig.class, StandaloneDataConfig.class,
JndiDataConfig.class);
ctx.refresh();
由于bean配置文件已设置为Dev
,TransferServiceConfig
将注入StandaloneDataConfig
答案 1 :(得分:0)
你基本上可以用@Configuration
类做同样的事情。
假设您有许多不同的DAO实现可能会或可能不会实现一个通用接口(它并不重要)。让我们进一步假设MyServiceDao
是您的Service
课程所需的具体实现。
编写以下配置类:
@Configuration
public class MyServiceConfiguration {
@Bean
public Service myService(MyServiceDao dao) {
return new Service(dao);
}
}
-
@Configuration
public class MyProductionServiceDaoConfiguration {
@Bean
public MyServiceDao myServiceDao() {
return new MyServiceDao();
}
}
使用@Configuration
注释的@Bean
类中的方法符合Spring的自动布线要求。在上面的MyServiceConfiguration
中,Spring将使用method参数的类型来查找匹配的bean。如果在创建Spring上下文时包含MyProductionServiceDaoConfiguration
,则这将是MyServiceDao
创建的myServiceDao()
的实例。
在测试中,您希望将MyServiceDao
替换为存根。存根需要扩展MyServiceDao
,以便Spring可以根据类型找到正确的bean。让我们调用存根MyServiceDaoStub
。无论您是使用像Mockito这样的库(也可以创建存根,而不仅仅是模拟)创建它,或者实际编写MyServiceDao
的扩展名都取决于您。
不要在Spring配置中包含MyProductionServiceDaoConfiguration
,而是使用以下类:
@Configuration
public class MyTestServiceDaoConfiguration {
@Bean
public MyServiceDao myServiceDao() {
return new MyServiceDaoStub();
}
}
在测试中使用@ContextConfiguration
加载测试设置:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyServiceConfiguration.class, MyTestServiceDaoConfiguration.classs })
public class MyServiceTest {
// your tests
}
Spring还将处理从@Autowired
带注释的方法返回的对象中的@Bean
注释。如果您的Service
看起来像这样:
public class Service {
@Autowired
private MyServiceDao dao;
// more code
}
您可以将myService()
方法更改为:
@Bean
public Service myService() {
return new Service();
}