Java getBean()应该延迟bean实例化吗?
我希望getBean()立即调用配置的@Bean方法,并使用SCOPE_PROTOTYPE创建Bean的新实例。然而,在调用bean的方法之前,这似乎不会发生。为什么装货延误了?如何使实例立即创建Java getBean()应该延迟bean实例化吗?,java,spring-boot,Java,Spring Boot,我希望getBean()立即调用配置的@Bean方法,并使用SCOPE_PROTOTYPE创建Bean的新实例。然而,在调用bean的方法之前,这似乎不会发生。为什么装货延误了?如何使实例立即创建 @Configuration public class ViewModelConfig { @Autowired MyService service; @Bean @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyM
@Configuration
public class ViewModelConfig {
@Autowired MyService service;
@Bean
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE, proxyMode = ScopedProxyMode.TARGET_CLASS)
public MyModel getModel() {
return new MyModel(service);
}
}
@Route
public class MyView extends FormLayout {
@Autowired private ApplicationContext context;
private MyModel model;
@PostConstruct
private void init() {
model = context.getBean(IntegrationViewModel.class); // Bean is retrieved but ViewModelConfig.getModel() not called and new instance from MyModel(MyService) not created yet
MyTreeGrid grid = new MyTreeGrid(model);
this.add(grid);
}
}
public class MyTreeGrid extends TreeGrid<MyTreeGridItem> {
private static final long serialVersionUID = -3198476593716788388L;
private MyModel model;
public MyTreeGrid(MyModel model){
this.model = model;
this.setItems(model.getItems()); // Before invoking model.getItems(), ViewModelConfig.getModel() is invoked, however the previous assignment of this.model is not updated with the new instance. Why is the loading delayed?
this.addItemClickListener(
new ComponentEventListener<ItemClickEvent<MyTreeGridItem>>() {
private static final long serialVersionUID = 8287268114264478411L;
@Override
public void onComponentEvent(ItemClickEvent<MyTreeGridItem> event) {
// event.getItem() never returns null
IntegrationTreeGrid.this.model.setSelectedItem(event.getItem()); // DOES NOT WORK!?! Appears to set the value when stepping through the function call, but after exiting the function call IntegrationTreeGrid.this.model.selectedItem remains null
}
});
}
}
public class MyModel {
private MyTreeGridItem selectedItem = null;
public void setSelectedItem(MyTreeGridItem item) {
this.selectedItem = item;
}
}
@配置
公共类ViewModelConfig{
@自动连线MyService服务;
@豆子
@范围(值=ConfigurableBeanFactory.Scope\u原型,proxyMode=ScopedProxyMode.TARGET\u类)
公共MyModel getModel(){
返回新的MyModel(服务);
}
}
@路线
公共类MyView扩展了FormLayout{
@自动连线专用应用程序上下文;
私有MyModel模型;
@施工后
私有void init(){
model=context.getBean(IntegrationViewModel.class);//已检索Bean,但未调用ViewModelConfig.getModel(),并且尚未创建MyModel(MyService)中的新实例
MyTreeGrid=新的MyTreeGrid(模型);
添加(网格);
}
}
公共类MyTreeGrid扩展了TreeGrid{
私有静态最终长serialVersionUID=-3198476593716788388L;
私有MyModel模型;
公共MyTreeGrid(MyModel模型){
this.model=模型;
this.setItems(model.getItems());//在调用model.getItems()之前,会调用ViewModelConfig.getModel(),但是this.model的上一个赋值不会用新实例更新。为什么加载会延迟?
这是addItemClickListener(
新组件EventListener(){
私有静态最终长serialVersionUID=8287268114264478411L;
@凌驾
组件事件(ItemClickEvent)的公共无效{
//event.getItem()从不返回null
IntegrationTreeGrid.this.model.setSelectedItem(event.getItem());//不起作用!?!在单步执行函数调用时显示以设置值,但在退出函数调用后IntegrationTreeGrid.this.model.selectedItem仍为空
}
});
}
}
公共类MyModel{
私有MyTreeGridItem selectedItem=null;
公共作废集合选择项(MyTreeGridItem项){
this.selectedItem=项目;
}
}
延迟初始化是因为proxyMode=ScopedProxyMode.TARGET\u CLASS
,它最终得到一个代理,该代理持有对原始bean定义的引用,并根据上下文创建/重用实际目标
由于您的bean具有范围“prototype”,这意味着您每次调用该代理上的方法时都会得到一个新实例,这很可能不是您想要的。您对该实例所做的任何操作都会“丢失”,因为每次方法调用都会创建一个新实例(这解释了您所看到的情况)。要测试这一点,请在MyModel
构造函数中设置断点
作用域代理在web上下文中最有意义,在web上下文中,您希望将某些组件绑定到请求或会话,但使用/注入它时将其视为一个单例。我的印象是在每个getBean()上都创建了一个新实例,感谢您的澄清!我是否应该使用不同的注释,或者我应该避免使用这个@configurationon类,而只是正常创建模型?您应该从注释中删除
proxyMode
属性,因为您根本不需要代理。如果没有这一点,它的行为将完全符合您的预期。