我有一个 dao 单元测试,声明如下:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/applicationContext.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class RegisterDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:/spring/applicationContext.xml");
private IRegisterDao registerDao = applicationContext.getBean(IRegisterDao.class);
当我运行单元测试时,一切都通过了,我可以看到数据库在单元测试执行之间重新创建。
我的测试数据库定义如下:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
<property name="url" value="jdbc:hsqldb:mem:test;sql.syntax_ora=true;create=true"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<jdbc:initialize-database data-source="dataSource" ignore-failures="DROPS">
<jdbc:script location="file:Artifacts/Hsql Version Scripts/install/droptables.sql" separator=";"/>
<jdbc:script location="file:Artifacts/Hsql Version Scripts/install/install.sql" separator="/;"/>
</jdbc:initialize-database>
但是当我将测试更改为使用下面定义的 @Autowired 时,它不会执行 init db 脚本。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/applicationContext.xml"})
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
public class RegisterDaoTest extends AbstractTransactionalJUnit4SpringContextTests {
/*
ApplicationContext applicationContext = new FileSystemXmlApplicationContext("classpath:/spring/applicationContext.xml");
private IRegisterDao registerDao = applicationContext.getBean(IRegisterDao.class);
*/
@Autowired
private IRegisterDao registerDao;
我不明白有什么区别。我有两个 applicationContext.xml,一个在主文件中,一个在测试文件中(这样我就可以用测试数据库覆盖数据库)
对我来说,它应该执行相同的操作。我错过了什么吗?
谢谢
最佳答案
默认情况下,Spring 上下文不会关注@Autowired 注释。为了处理它们,上下文需要在上下文中注册一个 AutowiredAnnotationBeanPostProcessor bean。
<context:annotation-config/>
为您注册其中一个(以及其他几个),因此您确实需要它(除非您自己注册 AutowiredAnnotationBeanPostProcessor,这是完全有效的)。
如果您不喜欢在代码中使用@Autowired,那么您可以使用 显式地在 XML 中注入(inject)属性,这只会将困惑从一个地方移动到另一个地方。
如果您的上下文非常简单,那么您可以使用隐式 Autowiring ,如here所述。 。本质上,这告诉 Spring 按属性名称或类型 Autowiring 。这需要很少的配置,但它很快就会失去控制 - 它的自动性质意味着它很难控制,并且给您带来很少的灵 active 。
总的来说@Autowired确实是最好的选择。
通过应用程序上下文,您可以自己注入(inject) bean。
默认情况下,Spring 容器中未启用注释连接。所以,在你之前 可以使用基于注释的 Autowiring ,您需要在 Spring 配置中启用它。 最简单的方法是使用
<context:annotation-config>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
...
</beans>
希望这有帮助。
关于spring - @Autowired 和从应用程序上下文获取 bean 有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9255606/