Spring DI-REST服务中的Autowired属性为null
我刚开始使用SpringDI,但我正在与依赖注入作斗争,更糟糕的是,我甚至不知道为什么,因为我觉得它还可以。希望你们能帮我 问题是注释为@Autowired的属性总是空的 我有几个Maven结构的项目: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
- com.diegotutor.lessondeliver
- com.diegotutor.utility
pom.xml
中使用了以下依赖项:
- spring上下文3.2.4
- SpringWeb3.2.4
- 泽西服务器1.17.1
- 泽西核心1.17.1
- 泽西servlet 1.17.1
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
整合:
<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>
谢谢大家! 另一个可能的选项是在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();
}
}
}