Spring DI-REST服务中的Autowired属性为null

Spring DI-REST服务中的Autowired属性为null,spring,dependency-injection,nullpointerexception,jersey,autowired,Spring,Dependency Injection,Nullpointerexception,Jersey,Autowired,我刚开始使用SpringDI,但我正在与依赖注入作斗争,更糟糕的是,我甚至不知道为什么,因为我觉得它还可以。希望你们能帮我 问题是注释为@Autowired的属性总是空的 我有几个Maven结构的项目: com.diegotutor.lessondeliver com.diegotutor.utility 我正在Tomcat7上运行这些示例 我在我的pom.xml中使用了以下依赖项: spring上下文3.2.4 SpringWeb3.2.4 泽西服务器1.17.1 泽西核心1.17.1

我刚开始使用SpringDI,但我正在与依赖注入作斗争,更糟糕的是,我甚至不知道为什么,因为我觉得它还可以。希望你们能帮我

问题是注释为@Autowired的属性总是空的

我有几个Maven结构的项目:

  • com.diegotutor.lessondeliver
  • com.diegotutor.utility
我正在Tomcat7上运行这些示例

我在我的
pom.xml
中使用了以下依赖项:

  • spring上下文3.2.4
  • SpringWeb3.2.4
  • 泽西服务器1.17.1
  • 泽西核心1.17.1
  • 泽西servlet 1.17.1
简单的想法是提供一个RESTful服务,通过依赖项注入,它能够打印出位于以下位置的配置文件中的属性值:
D:\configuracion.conf.

com.diegotutor.utility中,我有以下界面:

package com.diegotutor.utility;

public interface ConfigService {

    public String getProperty(final String propertyName);
}
执行人:

package com.diegotutor.utility.impl;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.Properties;

import com.diegotutor.utility.ConfigService;

public class PropertyFileConfigService implements ConfigService{

Properties prop;

public PropertyFileConfigService (final InputStream input) throws IOException {
    if(input == null) {
        throw new IllegalArgumentException("Input stream can't be null");
    }
    prop = new Properties();
    prop.load(input);
}

public PropertyFileConfigService (final String fileName) throws IOException {
    final FileInputStream input = new FileInputStream(fileName);
    prop = new Properties();
    prop.load(input);
}

public PropertyFileConfigService(final Reader input) throws IOException {
    prop = new Properties();
    prop.load(input);
}

public String getProperty(final String propertyName) {
    return prop.getProperty(propertyName);
}

}
com.diegotutor.lessondeliver我有一个RESTful服务,我想在其中使用注入的ConfigService实例:

package com.diegotutor.lessondeliver;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.diegotutor.utility.ConfigService;

@Path("/")
@Component
public class HelloWorld {

private static final Log log = LogFactory.getLog(HelloWorld.class);

@Autowired
private ConfigService configService;

@Path("/helloworld")
@GET
@Produces(MediaType.TEXT_PLAIN)
public String getHello() {
    String host = configService.getProperty("host");
    return "Hello World! HOST" + host;
            // configService IS NULL!! 
            //SO IT THROWS A NULLPOINTER EXCEPTION WHEN INVOKING getProperty ON IT
}
}
最后,在
/com.diegotutor.lessondeliver/src/main/webapp/WEB-INF/service beans.xml
中,我有以下xml应用程序上下文文件,其中我使用
配置服务(PropertyFileConfigService)
的实现在其上注入配置文件读取的路径:

<?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.xsd
   http://www.springframework.org/schema/context
   http://www.springframework.org/schema/context/spring-context.xsd">

<bean id="configService" class="com.diegotutor.utility.impl.PropertyFileConfigService">
    <constructor-arg type="java.lang.String"
        value="D:\configuracion.conf" />
</bean>

<context:component-scan base-package="com.diegotutor" />

</beans>
你是对的! 问题似乎在于Jersey完全不知道Spring,并实例化了自己的对象。为了让Jersey意识到Spring对象的创建(通过依赖项注入),我必须集成Spring+Jersey

整合:

  • 添加maven依赖项

    <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>
    
  • 现在@Autowired工作正常,对象不再为null

    当使用jersey spring依赖项时,我对maven中必须使用的排除有点困惑,但这是另一个问题:)


    谢谢大家!

    另一个可能的选项是在jersey资源中手动调用自动布线:

    @Context
    private ServletContext servletContext;
    
    @PostConstruct
    public void init() {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletContext);
    }
    

    嗯,你会得到一个“手动自动布线”…

    Jersey 2的集成Spring
    org.glassfish.
    ):

    专家 有些依赖关系可能是不必要的,请在事情正常后检查并清除它

        <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>
    
    示例REST服务
    或者,您可以简单地扩展SpringBeanAutoWiringSupport类。这样:
    公共类DemoRestService扩展了SpringBeanAutoWiringSupport
    。通过扩展此支持类,您的服务类的属性可以自动连接。

    请发布您的web.xml.Sotirios,感谢您的快速回复。我现在添加了web.xmlI缺少jersey spring集成-我不相信您看到的
    HelloWorld
    对象是spring生成的对象,因此该字段没有被注入。您可能想查看一些Spring Jersey集成。很好,我不知道Jersey和Spring在一起工作时可能会有冲突,需要集成,但如果Jersey正在实例化另一个HelloWorld,而完全不知道Spring@组件,这确实可以解释问题。我试试你说的。非常感谢你!你能粘贴所有的代码吗,因为我已经为这个任务花费了很多时间,-运气不好。我已经添加了示例。也许您应该首先验证所有注释。如果有帮助,请告诉我。答案是关于jersey 1.xPerfect!我只使用注释,不需要xml或maven依赖项混乱。
    @Context
    private ServletContext servletContext;
    
    @PostConstruct
    public void init() {
        SpringBeanAutowiringSupport.processInjectionBasedOnServletContext(this, servletContext);
    }
    
        <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>
    
    <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>
    
    <?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>
    
    public interface MyService
    {
        String work(String s);
    }
    
    ...
    
    @Service
    public class MyServiceImpl implements MyService
    {
        @Override
        public String work(String s)
        {
            return "Hello, " + s;
        }
    }
    
    ...
    
    @Path("demo/")
    @Component
    public 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();
            }
        }
    }