Spring bean如何与Prototype范围一起使用?

时间:2017-05-08 20:15:45

标签: spring dependency-injection

我有跟随Prototype范围的spring bean。在AppRunner类中,我希望在for循环中使用spring注入一个新bean(如果循环计数为2,那么我只需要注入2个新bean)。

但是每次调用SimpleBean的setter方法时,spring都会注入一个新的bean。

SimpleBean.java

@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = 
ScopedProxyMode.TARGET_CLASS)
public class SimpleBean {
    private String id;
    private Long value;
    public String getId() {
       return id;
    }

    public void setId(String id) {
       this.id = id;
    }

    public Long getValue() {
        return value;
    }

    public void setValue(Long value) {
        this.value = value;
    }
}

AppRunner.java

@Component
public class AppRunner {

    @Autowired
    SimpleBean simpleBean;

    public void execute(List<Output> results){
        List<SimpleBean> finalResults = new ArrayList<SimpleBean>();
        for(Output o : results){
            simpleBean.setId(o.getAppId());
            simpleBean.setValue(o.getAppVal());
            finalResults.add(simpleBean);
        }
    }
}

Output.java

public class Output {
    private String appId;
    private Long appVal;

    public String getAppId() {
        return appId;
    }

    public void setAppId(String appId) {
        this.appId = appId;
    }

    public Long getAppVal() {
        return appVal;
    }

    public void setAppVal(Long appVal) {
        this.appVal = appVal;
    }
}

1 个答案:

答案 0 :(得分:0)

不幸的是原型范围不像这样工作。当您的AppRunner bean被容器实例化时,它会询问它的依赖关系。然后创建SimpleBean的新实例。此实例保持为依赖性。当您有多个依赖于SimpleBean的bean时,原型范围开始工作。像:

@Component
class BeanOne {
    @Autowired
    SimpleBean bean; //will have its own instance
}

@Component
class BeanTwo {
    @Autowired
    SimpleBean bean; //another instance
}

有一个相当简单的更新可以导致您想要的行为。您可以删除自动连接的依赖项,并从上下文中请求循环中的新依赖项。它看起来像这样。

@Component
public class AppRunner {

    @Autowired
    ApplicationContext context;

    public void execute(List<Output> results){
        List<SimpleBean> finalResults = new ArrayList<SimpleBean>();
        for(Output o : results) {
            SimpleBean simpleBean = context.getBean(SimpleBean.class);
            simpleBean.setId(o.getAppId());
            simpleBean.setValue(o.getAppVal());
            finalResults.add(simpleBean);
        }
    }
}

其他选项可能是名为Method injection的技术。原型范围的相关文档中对此进行了描述。你可以看看7.5.3 Singleton beans with prototype-bean dependencies