Spring DI - Autowired property is null in a REST service Spring DI - Autowired property is null in a REST service spring spring

Spring DI - Autowired property is null in a REST service


You were right!It seems that the problem is that Jersey is totally unaware of Spring and instantiates its own object. In order to make Jersey aware of Spring object creations (through dependency injection) I had to integrate Spring + Jersey.

To integrate:

  1. Add maven dependencies

    <dependency>    <groupId>com.sun.jersey.contribs</groupId>    <artifactId>jersey-spring</artifactId>    <version>1.17.1</version>    <exclusions>        <exclusion>            <groupId>org.springframework</groupId>            <artifactId>spring-core</artifactId>        </exclusion>        <exclusion>            <groupId>org.springframework</groupId>            <artifactId>spring-beans</artifactId>        </exclusion>        <exclusion>            <groupId>org.springframework</groupId>            <artifactId>spring-context</artifactId>        </exclusion>        <exclusion>            <groupId>org.springframework</groupId>            <artifactId>spring-web</artifactId>        </exclusion>    </exclusions></dependency>
  2. Use SpringServlet for jersey-servlet in web.xml

    <servlet>    <servlet-name>jersey-servlet</servlet-name>    <servlet-class>        com.sun.jersey.spi.spring.container.servlet.SpringServlet    </servlet-class>    <load-on-startup>1</load-on-startup></servlet>

Now the @Autowired works properly and the object is not null anymore.

I'm a little bit confused about the exclusions I have to use in maven when using jersey-spring dependency, but that's another issue :)

Thank you!


Integration Spring with Jersey 2 (org.glassfish.*):

Maven

Some dependencies may be unnecessary, please check & clear it after things got working.

    <properties>        <jersey.version>2.5</jersey.version>    </properties>    <!-- Jersey -->    <dependency>        <groupId>org.glassfish.jersey.core</groupId>        <artifactId>jersey-server</artifactId>        <version>${jersey.version}</version>    </dependency>    <dependency>        <groupId>org.glassfish.jersey.containers</groupId>        <!-- if your container implements Servlet API older than 3.0, use "jersey-container-servlet-core" -->        <artifactId>jersey-container-servlet</artifactId>        <version>${jersey.version}</version>    </dependency>    <dependency>        <groupId>org.glassfish.jersey.core</groupId>        <artifactId>jersey-client</artifactId>        <version>${jersey.version}</version>    </dependency>    <dependency>        <groupId>org.glassfish.jersey.test-framework.providers</groupId>        <artifactId>jersey-test-framework-provider-inmemory</artifactId>        <version>${jersey.version}</version>    </dependency>    <!-- Jersey + Spring -->    <dependency>        <groupId>org.glassfish.jersey.ext</groupId>        <artifactId>jersey-spring3</artifactId>        <version>${jersey.version}</version>        <exclusions>            <exclusion>                <groupId>org.springframework</groupId>                <artifactId>spring</artifactId>            </exclusion>            <exclusion>                <groupId>org.springframework</groupId>                <artifactId>spring-core</artifactId>            </exclusion>            <exclusion>                <groupId>org.springframework</groupId>                <artifactId>spring-web</artifactId>            </exclusion>            <exclusion>                <groupId>org.springframework</groupId>                <artifactId>spring-beans</artifactId>            </exclusion>            <exclusion>                <groupId>org.springframework</groupId>                <artifactId>spring-context</artifactId>            </exclusion>        </exclusions>    </dependency>

web.xml

<servlet>    <servlet-name>my-rest-service</servlet-name>    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>    <init-param>        <param-name>jersey.config.server.provider.packages</param-name>        <param-value>my.package.with.rest.services</param-value>    </init-param>    <load-on-startup>1</load-on-startup></servlet><servlet-mapping>    <servlet-name>my-rest-service</servlet-name>    <url-pattern>/api/*</url-pattern></servlet-mapping>

applicationContext.xml

During the Spring upgrading I had to move it from /main/webapp/WEB-INF/ to /main/resources/ (details).

<?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"    xsi:schemaLocation="http://www.springframework.org/schema/beans    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd    http://www.springframework.org/schema/context    http://www.springframework.org/schema/context/spring-context-2.5.xsd">    <context:annotation-config />    <context:component-scan base-package="my.package.with.rest.services" /></beans>

Example REST service

public interface MyService{    String work(String s);}...@Servicepublic class MyServiceImpl implements MyService{    @Override    public String work(String s)    {        return "Hello, " + s;    }}...@Path("demo/")@Componentpublic class DemoRestService{    @Autowired    private MyService service;    @GET    @Path("test")    public Response test(@FormParam("param") String par)    {        try        {            String entity = service.work(par);            return Response.ok(entity).build();        }        catch (Exception e)        {            e.printStackTrace();            return Response.status(Status.INTERNAL_SERVER_ERROR).entity("Epic REST Failure").build();        }    }}


or you can simply extend SpringBeanAutoWiringSupport class. Like this: public class DemoRestService extends SpringBeanAutoWiringSupport. By extending this support class, properties of your service class can be auto-wired.