当 spring bean 的值为 value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS 时,我无法保持 bean 状态

I cannot keep the bean stateful when the spring bean is value = "prototype", proxyMode = ScopedProxyMode.TARGET_CLASS

这里是 spring bean:

@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

有什么帮助吗?谢谢!

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

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

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

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

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