【问题标题】:Spring bean properties persistingSpring bean 属性持久化
【发布时间】:2016-04-25 20:23:35
【问题描述】:

我有一个在 Spring 中自动装配的普通 POJO,其属性似乎保持不变。

我发现快乐的路径没问题 - 设置 bean 属性然后返回,但是当我不在快乐的路径上并且我不再希望设置属性(在本例中为 responseCode)时,我发现它仍然是设置为之前的值(调用成功时)。

我希望这个值不被设置并且等于我当前在模型中指定的值。

我有以下 POJO Prototype bean

package com.uk.jacob.model;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class Website {
    public String url;
    public boolean response;
    public int responseCode = 0;
}

我在服务类中设置它的信息

package com.uk.jacob.service;

import java.net.HttpURLConnection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.uk.jacob.adapter.HttpAdapter;
import com.uk.jacob.model.Website;

@Component
public class PingerService {

    @Autowired
    HttpAdapter httpAdapter;

    @Autowired
    Website website;

    public Website ping(String urlToPing) { 
        website.url = urlToPing;

        try {
            HttpURLConnection connection = httpAdapter.createHttpURLConnection(urlToPing);

            website.response = true;
            website.responseCode = connection.getResponseCode();
        } catch (Exception e) {
            website.response = false;
        }

        return website;
    }
}

从 RestController 调用

package com.uk.jacob.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.uk.jacob.model.Website;
import com.uk.jacob.service.PingerService;

@RestController
@RequestMapping("api/v1/")
public class PingController {

    @Autowired
    PingerService pingerService;

    @RequestMapping(value = "ping", method = RequestMethod.GET)
    public Website getPing(@RequestParam String url){
        return pingerService.ping(url);
    }

}

【问题讨论】:

    标签: java spring spring-mvc


    【解决方案1】:

    您的Website bean 是@Scope("prototype") 的事实意味着每次在创建此bean 时它作为依赖项注入另一个bean 时,都会创建并注入一个新实例。在这种情况下,PingerService 获得了一个新的 Website 实例。如果说Website 也被注入到另一个名为Website2 的bean 上,那么会注入一个不同的(新)实例。

    如果您的预期是 WebsiteWebsite 中的每次调用时都是新的,那么这不能简单地使用原型注释来完成。您需要公开上下文并调用ApplicationContext#getBean("website")

    【讨论】:

    • 您能详细解释一下ApplicationContext#getBean("website")?,它是什么吗?我的代码有什么问题?
    【解决方案2】:

    对于您的用例,我了解您需要为每个请求创建一个新的 Website bean 实例。

    使用@Scope("request")。

    另一方面,原型范围意味着它将为它随处可见的每个网站自动装配创建一个单独的实例。例如,PingerService 将拥有自己的 Website bean,并且不会在具有相同 Autowiring 的其他类上共享,但其值将在 PingerService 上的 http 请求中持续存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-18
      • 2012-01-05
      • 2016-02-08
      • 2013-11-06
      • 1970-01-01
      相关资源
      最近更新 更多