Why doesn't my Spring @autowired DAO get autowired?
The following works
Unit Test
package com.example.app.service;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.*;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/springcontext.xml"})
public class TestLeagueService {
@Autowired
LeagueService service;
@Test
public void test() {
assertNotNull(service.getLeagueDAO());
}
}
DAO
package com.example.app.dao.impl.hibernate;
public interface LeagueDAO {
}
Dao Impl
package com.example.app.dao.impl.hibernate;
public class LeagueHibernateDAO implements LeagueDAO {
public LeagueHibernateDAO() {
super();
}
}
Spring Context
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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/>
<context:component-scan base-package="com.example"/>
<bean id="LeagueDAO" class="com.example.app.dao.impl.hibernate.LeagueHibernateDAO" />
<bean id="LeagueService" class="com.example.app.service.LeagueService" />
</beans>
Marvo
I'm a software engineer at the University of California. I work primarily in Java, but have coded in C, C++, ObjC, Python, Perl, Pascal, Z80, 370 Assembler, and probably a bunch of other languages I've long since forgotten.
Updated on June 04, 2022Comments
-
Marvo almost 2 years
I am trying @autowired for the first time, and failing. I have read so many examples, and I seem to be doing everything right, but when my code hits my getLeagueDAO() method, the instance variable is set to null.
I have the following code:
package com.example.app.service; @Service public class LeagueService { // also tried @Autowired here, and that didn't work private LeagueDAO leagueDao; // = new LeagueHibernateDAO(); public LeagueDAO getLeagueDAO() { return this.leagueDao; } @Autowired public void setLeagueDAO( LeagueDAO dao ) { this.leagueDao = dao; } [ ... ]
LeagueHibernateDAO:
package com.example.app.dao.impl.hibernate; import ... public class LeagueHibernateDAO implements LeagueDAO { public LeagueHibernateDAO() { super(); } [ ... ]
My *-servlet.xml file:
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:p="http://www.springframework.org/schema/p" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd 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/> <context:component-scan base-package="com.example"/> <mvc:annotation-driven /> <bean id="LeagueDAO" class="com.example.app.dao.impl.hibernate.LeagueHibernateDAO" /> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <property name="prefix" value="/jsp/"/> <property name="suffix" value=".jsp"/> </bean> </beans>
My Spring dependencies are:
... <org.springframework.version>3.0.6.RELEASE</org.springframework.version> ... <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency>
My unit tests don't run. My app doesn't run. All because leagueDao isn't being set in LeagueService. Why isn't it getting wired?
My Full Solution
For the benefit of anyone who comes along with similar issues...
1) It's clear I didn't know how to write a test of autowired code. The accepted answer provides a working example of how to do this.
2) It appears that with autowiring, it's essentially all-or-nothing. I had already created an application and wanted to go back and autowire it. So I thought I would start small and autowire the LeagueDAO into the LeagueService. However, because the LeagueServiceTest didn't autowire LeagueService, it wouldn't wire up references to LeagueDAO. Once I properly autowired each step in the chain, everything worked.
So when I tried to run my application, even though my tests now worked, my application again was not autowiring. To fix things, I finally realized I had to fully autowire another chain. In this case, I already had LeagueDAO plugged into LeagueService. The problem was that LeagueService is invoked by a controller, which was simply instantiating the LeagueService class by invoking the constructor. When I autowired LeagueService into the controller, everything began to work.
I have read so much stuff on this, and if that's explained anywhere, it wasn't explained in a way that was clear to me. Arrrgh.