What's the difference between @Autowired and getting a bean from the application context?
By default, a Spring context will pay no attention to @Autowired annotations. In order to process them, the context needs to have a AutowiredAnnotationBeanPostProcessor bean registered in the context.
<context:annotation-config/>
registers one of these for you (along with a few others), so you do need it (unless you register AutowiredAnnotationBeanPostProcessor yourself, which is perfectly valid).
If you don't like having @Autowired in your code, then you can explicitly inject properties in the XML using , which just moves the clutter from one place to another.
If your context is extremely simple, then you can use implicit autowiring, as described here. Essentially, this tells Spring to autowire automatically by property name or type. This required very little configuration, but it very quickly gets out of control - it's automatic nature means it's hard to control, and gives you very little flexibility.
In general @Autowired really is the best option.
With application context, you are injecting the bean by yourself.
Annotation wiring isn’t turned on in the Spring container by default. So, before you can use annotation-based autowiring, you'll need to enable it in your Spring configuration. The simplest way to do that is with the
<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>
Hope this helps.
Eric
Updated on June 13, 2022Comments
-
Eric almost 2 years
I have a dao unit test that is declared as follows:
@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);
When I run the unit test, all pass and I can see the db getting recreated in between unit test executions.
My test db is defined as follows:
<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>
But when I change my test to use @Autowired, defined below, it does not execute the init db scripts.
@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;
I don't see what the difference is. I have two applicationContext.xmls, one in the main and one in the test (so I can override the db with the test db)
To me, it should execute the same. Am I missing something?
Thanks,