【问题标题】:Spring Boot dependency injecting with request scoped beans使用请求范围的 bean 注入 Spring Boot 依赖项
【发布时间】:2017-04-25 10:49:59
【问题描述】:

我正在尝试将一个 bean 依赖注入到另一个中,但我想通过简单地直接自动装配到类中来做到这一点,而不是通过“@Configuration 类”。这是控制器类:

@Controller
public class RestfulSourceController {

    @Autowired
    Response response;

    @RequestMapping(value="/rest", method=RequestMethod.GET, produces="application/json")
    @ResponseBody
    public Object greeting() {
        return response.getResponse();
    }

}

这里是“@Configuration”类,每个类都声明了一个 bean

@Configuration
class RequestConfigurationBeans {

    @Autowired
    private ServicesRepository servicesRepo;

    @Autowired
    private HttpServletRequest request;

    @Bean(name = 'requestServiceConfig')
    @Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
    public ServiceModel requestServiceConfig(){
        String serviceName = RequestUtil.getServiceName(this.request)
        ServiceModel serviceModel = servicesRepo.findByName(serviceName)
        return serviceModel
    }

}

@Configuration
public class ServletFilterBeans {

    /* I don't want to autowire here, instead I want to autowire in the Response class directly, instead of passing the bean reference into the constructor
    @Autowired
    ServiceModel requestServiceConfig
    */

    @Bean
    @Scope(value=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
    public Response response(){
        return new Response(/*requestServiceConfig*/);
    }

}

最后是 Response 类:

class Response {

    //I want to Autowire the bean instead of passing the reference to the constructor
    @Autowired
    ServiceModel requestServiceConfig

    Object response

    public Response(/*ServiceModel requestServiceConfig*/){
        //this.requestServiceConfig = requestServiceConfig

        if (requestServiceConfig.getType() == 'rest'){
            this.response = getRestfulSource()
        }

    }


    private Object getRestfulSource(){
        RestTemplate restTemplate = new RestTemplate()
        String url = requestServiceConfig.sourceInfo.get('url')
        return restTemplate.getForObject(url, Object.class)
    }
}

然而,当我像这样设置依赖注入时,我得到一个空指针异常,因为自动装配的 bean“requestServiceConfig”没有被实例化。如何通过自动装配依赖注入 bean,这样我就不必通过构造函数传递对 bean 的引用?

【问题讨论】:

  • NPE 从何而来? if (requestServiceConfig.getType() == 'rest'){ 行?
  • "type" 是 ServiceModel 类中的一个字段。 “requestServiceConfig”是该类的一个实例。这是 groovy 代码,所以我不需要使用“.equals”方法。

标签: java spring web-services spring-mvc


【解决方案1】:

问题是Response的构造函数中requestServiceConfig的使用。自动装配只能在对象创建后发生,所以这里的依赖只能为空。

为了解决问题并能够使用自动装配,您可以将代码从构造函数移动到 @PostConstruct 生命周期方法:

@PostConstruct
private void init() {
    if ("rest".equals(this.requestServiceConfig.getType())) {
        this.response = getRestfulSource();
    }
}

【讨论】:

  • 那行不通。无论如何,他的 Response bean 已经由 Spring 在“ServletFilterBeans”类中使用@Configuration 注释进行管理。
  • 啊,错过了。奇怪的是你得到了一个 NPE。我以为 Spring 会抱怨无法自动装配 bean。难道自动装配不是问题,requestServiceConfig() 只是返回 null 吗?
  • 我认为这不是问题,因为如果我将 bean requestServiceConfig 直接传递给 Response 构造函数,它就可以正常工作(参见注释代码)。我计划在许多其他 bean 中使用 requestServiceConfig,这就是为什么我不想通过构造函数来管理注入,而是我想在 bean 类中使用一个简单的 Autowired 注解。
  • 我能够重现该问题并相应地编辑了我的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-01-21
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-21
  • 1970-01-01
相关资源
最近更新 更多