【问题标题】:I cannot keep the bean stateful when the spring bean is value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS当 spring bean 为 value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS 时,我无法保持 bean 有状态
【发布时间】:2015-02-23 06:53:21
【问题描述】:

这是春豆:

@Repository
@Scope(value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class TestBean {
    private String text;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }
}

这是访问 bean 的非常简单的代码:

    TestBean testBean = (TestBean) SpringContext.getBean("testBean");//#1
    testBean.setText("aaaaa"); //#2
    System.out.println(testBean.getText()); //#3

结果是 testBean.getText() 为空。

当我尝试调试代码时,我发现 #2 中的 testBean 实例与 #3 中的实例不同。例如:

#2:TestBean@988995e #3:TestBean@69bf7e71

有什么帮助吗?谢谢!

【问题讨论】:

    标签: spring proxy prototype javabeans


    【解决方案1】:

    SpringContext.getBean("testBean") 为您返回 Proxy 对象。并且任何方法调用都是对DynamicAdvisedInterceptor 的委托。反过来,target = getTarget(); 会生成CglibMethodInvocation。而魔法隐藏在getTarget() 中,它是SimpleBeanTargetSourceprototype bean,并且有一个代码:

    public Object getTarget() throws Exception {
        return getBeanFactory().getBean(getTargetBeanName());
    }
    

    因此,TestBean 上的任何方法调用都会向 BeanFactory 询问该类的新实例。这就是为什么你的setText("aaaaa")testBean.getText() 不可见,因为每个方法都针对它的TestBean 对象,不一样。

    无法从代码中手动更改此类 prototype 对象。它们由ApplicationContext 管理,只有最后一个可以填充它们的内部状态。从代码中您只能阅读它们。

    如果您的TestBean 填充了相同的值,您将从testBean.getText() 获得相同的值,但所有这些调用将针对不同的对象完成。

    【讨论】:

    • 感谢您的精彩解释!我发现如果我将其更改为 ScopedProxyMode.INTERFACES,它就可以工作。你能告诉我是否有办法在我从 getBean() 获取后获取相同的 cglib 代理 bean,而不是每次调用获取的 bean 的方法时获取一个新实例?
    • 根本不要做代理!因为它是 prototype,所以你无法通过代理来克服 object-per-invocation 的问题。
    猜你喜欢
    • 1970-01-01
    • 2011-05-29
    • 2015-05-09
    • 1970-01-01
    • 2015-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多