问题
i'm learning spring now. here's my sample code. i'm using jersey, spring, hibernate, and mysql for my REST service.
CustomerServiceImpl.java
which is REST endpoint (partial code)
package com.samples.service.impl;
@Path("customers")
public class CustomerServiceImpl implements CustomerService {
private static Logger logger = Logger.getLogger(CustomerServiceImpl.class);
@Autowired
CustomerBO customerBO;
here is CustomerBOImpl.java
(partial code)
package com.samples.BO.impl;
@Component
public class CustomerBOImpl implements CustomerBO {
@Autowired
CustomerDAO customerDAO;
@Autowired
CustomerAdapter customerAdapter;
CustomerDAOImpl.class package com.samples.DAO.impl;
@Repository
public class CustomerDAOImpl implements CustomerDAO {
this is applicationContext.xml
<?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:tx="http://www.springframework.org/schema/tx"
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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
<context:property-placeholder location="classpath*:database.properties"/>
<context:component-scan base-package="com.samples"/>
<context:annotation-config />
</beans>
this is first few lines of exception i'm getting.
http-bio-8090-exec-1] [class: CustomerServiceImpl] INFO - list all customers
[http-bio-8090-exec-1] [class: CustomerServiceImpl] INFO - customerBO is null
May 08, 2014 10:55:29 AM com.sun.jersey.spi.container.ContainerResponse mapMappableContainerException
SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
java.lang.NullPointerException
at com.samples.service.impl.CustomerServiceImpl.getAllCustomers(CustomerServiceImpl.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvo
this is web.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
version="2.5">
<display-name>Employee Service</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
classpath*:applicationContext.xml
</param-value>
</context-param>
<context-param>
<param-name>initializeContextOnStartup</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>jersey-serlvet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.samples.service</param-value>
</init-param>
<init-param>
<param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>jersey-serlvet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
so if i'm understanding how this works correctly, i'm configuring xml
to have my components autoscanned by providing the package under which i want to run autoscan. and for objects that i want to autowire. in CustomerServiceImpl
class, i use @autowired for customerBO
object which should have been scanned by @Component annotation on CustomerBOImpl.class definition. can you please help why my auto-scan is not picking up autowired customerBO object?
thanks.
回答1:
I suspect the problem is your CustomerServiceImpl
class is being instantiated outside of Spring, either by the servlet container or explicitly in your code. You need to either have Spring instantiate it (by making it a bean
, etc) or use <context:spring-configured/>
. I'm not sure if the latter will work if the servlet container instantiates the object as it will likely depend on the order in which things occur...
回答2:
Spring only know to autowire fields that have been marked as beans. From your code CustomerDAO
is not a bean. For example to define it as a bean in the xml configuration file you need to add
<bean id="customerDao" class="com.packagesNames.CustomerDaoImpl"/> in the xml file.
or to have the class annotated with @Component
or to have it defined with @Bean
in a @Configuration
class.
回答3:
Jersey 2 and Spring integration is now supported.
Jersey Docs: Chapter 22. Spring DI
Blog: Implementing Jersey 2 Spring Integration
Sample App: Jersey's Hello World Spring WebApp
However, as of this writing, Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration. Annotations (@Autowired
, etc.) must be used.
回答4:
I had the same problem. My injected bean in the resource class was always coming as NULL
.
I spent 2 days trying to figure it out why I can't inject the Spring Bean into the JAX-RS resource class. Then I found the below in the Jersey documentation:
"Limitations:
Spring beans can't be injected directly into JAX-RS classes by using Spring XML configuration"
Note: I was using Jersey 2 and Spring 3.x in my project.
来源:https://stackoverflow.com/questions/23549322/spring-autowire-is-not-working-returning-null