spring - @Autowired 和从应用程序上下文获取 bean 有什么区别?

标签 spring junit autowired

我有一个 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/

相关文章:

java - 在 IntelliJ IDEA 中显示未使用的 Autowiring 字段的警告

spring - 使用实现 ApplicationListener 的 @Autowired 注入(inject)一个 bean 不起作用?

java - JUnit + Derby + Spring : drop in-memory db after every test

java - 用于删除重复的 Oracle SQL Db 表条目的 NativeQuery 不起作用(请参阅代码)

java - 如何在 Ant 中仅运行特定的 JUnit 测试?

java - 构建spring框架源码遇到错误

java - Autowired 服务的 ScheduledExecutorService 问题

java - 如何在 Spring 中为 View 路径设置自定义 View 解析器

java - 创建名称为 'org.springframework.security.filterChains' Spring + Hibernate + UserDetailSservice 的 bean 时出错

Spring MVC XML 结果分块,缺少 Content-length header