简体   繁体   English

使用@Autowired属性时为NPE(但使用ApplicationContext设置属性时不为NPE)

[英]NPE when using @Autowired property (but not when using ApplicationContext to set property)

I'm trying to use the @Autowired annotation to set a property on a jax-rs restful service but I get a null pointer exception when the property is referenced. 我正在尝试使用@Autowired批注在jax-rs restful服务上设置属性,但是当引用该属性时,我会得到一个空指针异常。 This is the first time I've tried using this annotation. 这是我第一次尝试使用此批注。

package com.pallelli.mvcpract.rest;

import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.web.context.support.WebApplicationContextUtils;

import com.pallelli.hibpract.policymodel.PolicyDao;
import com.pallelli.hibpract.policymodel.beans.Risk;

@Service("riskService")
@Path("risk")
@Component
public class RiskService {

    //@Context
    //private ServletContext context; 

    @Autowired
    private PolicyDao policyDao;

    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response storeRisk(Risk risk) {

        //ApplicationContext ctx = 
        //WebApplicationContextUtils.getWebApplicationContext(context);
        //policyDao = ctx.getBean(PolicyDao.class);

        policyDao.addRisk(risk);
        risk.setName(risk.getName()+" : processed");
        return Response.ok(risk).status(200).build();
    }
}

Everything works if I remove the comments so that policyDao is created using an application context, hence I think that spring is being made aware of the bean. 如果删除注释,则一切正常,以便使用应用程序上下文创建policyDao,因此,我认为spring已经意识到了bean。

I'm using the following in mvc-dispatcher-servlet.xml to get spring to look for the beans. 我在mvc-dispatcher-servlet.xml中使用以下内容来获取spring以查找bean。

<context:component-scan base-package="com.pallelli.mvcpract.rest" />
<context:component-scan base-package="com.pallelli.hibpract.policymodel" />

This is the PolicyDao class (and I know that it is 'wrong') 这是PolicyDao类(我知道这是“错误的”)

package com.pallelli.hibpract.policymodel;

import org.hibernate.Session;
import org.springframework.stereotype.Component;

import com.pallelli.hibpract.policymodel.beans.Risk;

@Component
public class PolicyDao {
    public void addRisk(Risk risk) {
        Session session = null;
        try {
            session = Main.getSessionFactory().openSession();
            session.beginTransaction();
            session.persist(risk);
            session.getTransaction().commit();
        }
        finally {
            if(session != null) session.close();
        }
    }
}

The debug log seems to suggest that the autowiring worked 调试日志似乎表明自动装配有效

20:10:41 DEBUG DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'riskService'
20:10:41 DEBUG DefaultListableBeanFactory:449 - Creating instance of bean 'riskService'
20:10:41 DEBUG InjectionMetadata:71 - Registered injected element on class [com.pallelli.mvcpract.rest.RiskService]: AutowiredFieldElement for private com.pallelli.hibpract.policymodel.PolicyDao com.pallelli.mvcpract.rest.RiskService.policyDao
20:10:41 DEBUG DefaultListableBeanFactory:523 - Eagerly caching bean 'riskService' to allow for resolving potential circular references
20:10:41 DEBUG InjectionMetadata:85 - Processing injected method of bean 'riskService': AutowiredFieldElement for private com.pallelli.hibpract.policymodel.PolicyDao com.pallelli.mvcpract.rest.RiskService.policyDao
20:10:41 DEBUG DefaultListableBeanFactory:220 - Creating shared instance of singleton bean 'policyDao'
20:10:41 DEBUG DefaultListableBeanFactory:449 - Creating instance of bean 'policyDao'
20:10:41 DEBUG DefaultListableBeanFactory:523 - Eagerly caching bean 'policyDao' to allow for resolving potential circular references
20:10:41 DEBUG DefaultListableBeanFactory:477 - Finished creating instance of bean 'policyDao'
20:10:41 DEBUG AutowiredAnnotationBeanPostProcessor:427 - Autowiring by type from bean name 'riskService' to bean named 'policyDao'
20:10:41 DEBUG DefaultListableBeanFactory:477 - Finished creating instance of bean 'riskService'
...
20:18:45 DEBUG DefaultListableBeanFactory:247 - Returning cached instance of singleton bean 'policyDao'

Any ideas as to why the autowired property on RiskService is null? 关于为何RiskService上的autowired属性为null的任何想法?

It seems like jax-rs is not able to process Spring annotations. 看来jax-rs无法处理Spring注释。

Some additional setup is required to make jax-rs objects aware of Spring Beans. 为了使jax-rs对象了解Spring Bean,还需要一些其他设置。 Without proper initialization Autowired, Transactional or any other Spring annotation is not processed. 没有正确的初始化,自动连线,事务性或任何其他Spring注释都不会被处理。

Assuming that you are using Jersey and Spring 3 you need to include library which provides a "bridge" between Jersey and Spring: 假设您使用的是Jersey和Spring 3,则需要包括一个提供在Jersey和Spring之间的“桥梁”的库:

<dependency>
    <groupId>org.glassfish.jersey.ext</groupId>
    <artifactId>jersey-spring3</artifactId>
    <version>2.22.1</version>
</dependency>

There is a separate library which provides support for Spring 4. For details see Jersey documentation and this example . 有一个单独的库为Spring 4提供支持。有关详细信息,请参见Jersey 文档和本示例

You managed to get ApplicationContext as it is stored as an attribute in ServletContext so it can be retrieved from any place in the application using static method call. 您设法获得了ApplicationContext,因为它作为属性存储在ServletContext中,因此可以使用静态方法调用从应用程序中的任何位置检索它。 As you noticed beans are properly initialized but both frameworks just do not talk to each other. 如您所见,bean已正确初始化,但是两个框架都无法互相通信。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用CamelBlueprintTestSupport时的NPE - NPE when using CamelBlueprintTestSupport 使用休眠初始化实体时在实体中设置属性 - Set property in an entity when it is initialized using hibernate 在JUnit Jupiter中使用自定义组合注释时,为@Autowired bean获取NPE - Getting NPE for @Autowired bean when using custom composed annotation in JUnit Jupiter 当该bean已经通过xml设置了另一个属性时,是否可以通过自动装配注入属性? - Is it possible to inject a property through autowired when that bean already has another property set through xml 当我在构造函数中调用它时,自动装配的属性是 null - Autowired property is null when I call it in constructor @ Autowired,@ Resource和使用属性注入的春季性能 - Spring performance for @Autowired, @Resource and using property injection 使用Autowired的Spring Java Config导致了NPE - Spring Java Config using Autowired caused NPE Mockito 在使用 when 时抛出 NPE - Mockito throws NPE when using when Spring MVC-使用@ResponseBody时设置JAXB marshaller属性 - Spring MVC - set JAXB marshaller property when using @ResponseBody 将RestTemplate与Spring for Android结合使用时如何在Abstract类中设置属性 - How to set a property in Abstract class when using RestTemplate with Spring for Android
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM