当 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()
获得相同的值,但所有这些调用将针对不同的对象完成。
这里是 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()
获得相同的值,但所有这些调用将针对不同的对象完成。