Spring Autowired in Web Service not working

14,040

SpringBeanAutowiringSupport must be a bean. You need to annotate that class with @Service or another annotation such as @Component that indicates a class should be a bean when component scanning occurs. These will be picked up by Spring and made into beans.

Remember that in order to be a participant in autowiring, such as having another bean injected, the class must be a bean itself and managed by Spring's IOC container.

Share:
14,040
user3207820
Author by

user3207820

Updated on June 05, 2022

Comments

  • user3207820
    user3207820 almost 2 years

    I must be missing something simple, but I'm having trouble getting an Autowired property to be assigned to a bean. All similar answers posted here seem to revolve around one of three solutions:

    1. extend SpringBeanAutowiringSupport
    2. use <context:component-scan base-package="..." /> in applicationContext.xml
    3. use <context:annotation-config /> in applicationContext.xml

    I tried to make a minimalist bean to represent my DAO and inject it into a Web Service.

    DAO interface:

    package wb;
    public interface FooDAO {
        public String doNothing();
    }
    

    DAO implementation:

    package wb;
    import org.springframework.stereotype.Component;
    
    @Component
    public class FooDAOImpl implements FooDAO {
        public FooDAOImpl() {
            System.out.println("FooDAOImpl: Instantiated " + this);
        }
    
        @Override
        public String doNothing() {
            System.out.println("FooDAOImpl: doNothing() called");
            return "Did nothing!";
        }
    }
    

    Web Service with injection:

    package ws;
    
    import javax.jws.WebService;
    import javax.jws.WebMethod;
    import javax.jws.WebResult;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.context.support.SpringBeanAutowiringSupport;
    import wb.FooDAO;
    
    @WebService(serviceName = "WS")
    public class WS extends SpringBeanAutowiringSupport {
    
        @Autowired(required = true)
        private FooDAO fooDAO;
    
        @WebMethod(exclude = true)
        public void setFooDAO(FooDAO fooDAO) {
            this.fooDAO = fooDAO;
            System.out.println("WS: fooDAO set = " + fooDAO);
        }
    
        public WS() {
            System.out.println("WS: WS bean instantiated!");
        }
    
        @WebMethod(operationName = "doNothing")
        @WebResult(name = "whatDidIDo")
        public String doNothing() {
            System.out.println("WS: doNothing() says DAO = " + fooDAO);
            return fooDAO == null ? "Could not do nothing!" : fooDAO.doNothing();
        }
    }
    

    applicationContext.xml content within the beans tags:

    <context:annotation-config />
    <context:component-scan base-package="ws"/>
    
    <bean id="fooDAO" class="wb.FooDAOImpl" />
    

    This was all created in the latest NetBeans, in a project created with Spring and Hibernate frameworks. When I deploy to JBoss, and the app starts up, I get the expected Bean instantiation:

    11:01:46,767 INFO  [stdout] (MSC service thread 1-6) WS: WS bean instantiated!
    11:01:47,571 INFO  [stdout] (MSC service thread 1-15) FooDAOImpl: Instantiated wb.FooDAOImpl@11176682
    

    Once I call the web service, the log also reports:

    11:03:07,097 INFO  [stdout] (http--127.0.0.1-8080-1) WS: doNothing() says DAO = null
    

    What am I missing?

  • user3207820
    user3207820 over 10 years
    Thanks; could have sworn that's one of the things I'd tried previously. When I add @Component, it works.
  • Kevin Bowersox
    Kevin Bowersox over 10 years
    @user3207820 Glad I could help. I struggled with some the same concepts early on when using Spring. Anytime you use the new keyword you really need to pause and wonder if its appropriate.
  • user3207820
    user3207820 over 10 years
    The WS instance created during App startup gets an auto-wired DAOImpl. But when calling the web service, a different WS instance is created to field the requests, and THAT instance doesn't get one. Weird. Anyway, thanks again.
  • Jurgen Camilleri
    Jurgen Camilleri about 7 years
    I'm experiencing the same exact thing as the above comment. I can't get the instance created when calling the web service to have the autowired fields. Am I doing something wrong with how I'm creating the web service? Or did I not follow the solution correctly? Spring is definitely creating the WS class as a bean, but it's not the same instance used when calling the service.