Spring Autowired in Web Service not working
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.
user3207820
Updated on June 05, 2022Comments
-
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:
- extend SpringBeanAutowiringSupport
- use <context:component-scan base-package="..." /> in applicationContext.xml
- 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 over 10 yearsThanks; could have sworn that's one of the things I'd tried previously. When I add @Component, it works.
-
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 over 10 yearsThe 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 about 7 yearsI'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.