我在osx上使用Eclipse的Spring版本3.0.6并且不明白为什么我不能为bean设置任何属性。部分代码:
@Component("desktopBuilderCallback")
@Scope("prototype")
public class DesktopBuilderCallback implements BuilderCallback {
private Socket desktopSocket;
@Override
public Transformation afterTransform(Transformation transformation)
throws Exception {
\\ some implementation
}
@Override
public void handleStatusUpdate(Transformation transformation)
throws Exception
{
\\ some implementation
}
public Socket getDesktopSocket() {
return desktopSocket;
}
public void setDesktopSocket(Socket desktopSocket) {
this.desktopSocket = desktopSocket;
}
}
@Component("transformationBuilder")
@Scope("prototype")
public class TransformationBuilder implements Runnable,
SourceNotificationCallback, TargetNotificationCallback,
ApplicationContextAware {
int test;
BuilderCallback builderCallback;
public BuilderCallback getBuilderCallback() {
return builderCallback;
}
public void setBuilderCallback(BuilderCallback builderCallback) {
this.builderCallback = builderCallback;
}
public int getTest() {
return this.test;
}
public void setTest(int theTest) {
this.test = theTest;
}
}
public static void main(String[] args) throws IOException {
TransformationBuilder transformationBuilder = (TransformationBuilder) ctx.getBean("transformationBuilder");
DesktopBuilderCallback callback = (DesktopBuilderCallback) ctx.getBean("desktopBuilderCallback");
transformationBuilder.setBuilderCallback(callback);
transformationBuilder.setTest(5);
}
执行代码后,将不会初始化test和builderCallback。 test将为0且builderCallback为零。不确定它是怎么可能的,我是java和spring的新手......但是我已经检查过调试器跳转到setter(setTest,setBuilderCallback),可能是因为项目是为JRE 1.5开发的,但我是使用1.8 ...
答案 0 :(得分:2)
从您发布的代码到目前为止,我猜您的问题与将bean的范围设置为prototype
有关。
来自spring docs:
bean的非单例原型范围部署导致每次发出特定bean的请求时都会创建一个新的bean实例(也就是说,它被注入另一个bean或者它是通过对容器的程序化getBean()方法调用请求的。根据经验,您应该将原型范围用于所有有状态的bean,而单例范围应该用于无状态bean。
这是每次从应用程序上下文(transformationBuilder
)获取ctx.getBean("transformationBuilder")
bean时,您将获得TransformationBuilder
的新实例。每个不属于标准bean初始化过程的手动初始化都不会在这些实例中可用。
要正确初始化bean,可以使用@Value
注释从配置中注入值,使用@Autowired
注入其他bean实例,或使用@PostConstruct
方法执行其他非bean - 通过初始化。
对于你的课程,这可能是这样的:
@Component("transformationBuilder")
@Scope("prototype")
public class TransformationBuilder implements Runnable,
SourceNotificationCallback, TargetNotificationCallback,
ApplicationContextAware {
// either use the value of the property 'some.property.key' or 5 as default
@Value("${some.property.key:5}")
int test;
@Autowired
@Qualifier("desktopBuilderCallback")
BuilderCallback builderCallback;
...
}
当然,您也可以使用singleton
范围(实际上是spring bean的默认范围)。每次请求此bean时,这将导致spring返回相同实例。但是对于singleton
范围,bean的初始化也应该由DI容器处理。