Why doesn't my Spring @autowired DAO get autowired?

14,553

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>
Share:
14,553
Marvo
Author by

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, 2022

Comments

  • Marvo
    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.