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

Eri*_*ric 6 junit spring 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);
Run Code Online (Sandbox Code Playgroud)

当我运行单元测试时,所有通过,我可以看到在单元测试执行之间重新创建数据库.

我的测试数据库定义如下:

    <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>
Run Code Online (Sandbox Code Playgroud)

但是,当我将测试更改为使用@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;
Run Code Online (Sandbox Code Playgroud)

我不明白有什么区别.我有两个applicationContext.xmls,一个在main中,一个在测试中(所以我可以用测试db覆盖db)

对我来说,它应该执行相同的.我错过了什么吗?

谢谢,

Nom*_*mad 7

默认情况下,Spring上下文不会关注@Autowired注释.为了处理它们,上下文需要在上下文中注册AutowiredAnnotationBeanPostProcessor bean.

<context:annotation-config/>
Run Code Online (Sandbox Code Playgroud)

为你(以及其他一些)注册其中一个,所以你确实需要它(除非你自己注册AutowiredAnnotationBeanPostProcessor,这是完全有效的).

如果您不喜欢在代码中使用@Autowired,那么您可以使用XML显式地注入属性,这只会将混乱从一个地方移动到另一个地方.

如果你的环境是非常简单的,那么你可以使用隐自动装配,如所描述这里.从本质上讲,这告诉Spring按属性名称或类型自动自动装配.这需要非常少的配置,但它很快失控 - 它的自动性意味着它很难控制,并且给你很小的灵活性.

一般来说@Autowired确实是最好的选择.

使用应用程序上下文,您可以自己注入bean.

默认情况下,Spring容器中未打开注释接线.因此,在使用基于注释的自动装配之前,您需要在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>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.