Java 如何设计依赖于实例创建顺序的类的DI
这感觉像是一个相当标准的问题,以前可能有人问过,但我发现很难找到,因为很难用语言来定义。所以,如果这是一个重复,继续和重定向我 我正在使用Vaadin来构建这个web应用程序,但这对手头的问题不重要,除非有更好的方法通过Vaadin魔法来解决这个问题 我有三门课:Java 如何设计依赖于实例创建顺序的类的DI,java,oop,design-patterns,vaadin,vaadin7,Java,Oop,Design Patterns,Vaadin,Vaadin7,这感觉像是一个相当标准的问题,以前可能有人问过,但我发现很难找到,因为很难用语言来定义。所以,如果这是一个重复,继续和重定向我 我正在使用Vaadin来构建这个web应用程序,但这对手头的问题不重要,除非有更好的方法通过Vaadin魔法来解决这个问题 我有三门课: 桌子 过滤器发生器 容器 我的“设计”如下所示: 容器在其构造函数中向自身添加一些属性(列标题) FilterGenerator@注入容器(以便使用容器的getDistinct()方法从容器中获取不同的项-以便在过滤器的组合框中
- 桌子
- 过滤器发生器
- 容器
- 容器在其构造函数中向自身添加一些属性(列标题)
- FilterGenerator@注入容器(以便使用容器的getDistinct()方法从容器中获取不同的项-以便在过滤器的组合框中很好地显示它们)
- 表@注入FilterGenerator(以便表.setFilterGenerator(FilterGenerator))
- 表@注入容器并调用containers addItems()方法将项添加到容器中
- 表将容器添加为数据源
映射,因为在FilterGenerator中@Inject时,表还没有调用Containers addItems()方法,所以此时容器将是空的
问题
如果我想让一个组件(FilterTable)从第二个组件(容器)中获取一些东西,当第三个组件(表)正在@Inject注入上述两个组件时,我应该如何设计这个应用程序?当第一个组件(FilterGenerator)启动时,第二个组件(容器)已经初始化是至关重要的从中获取一些信息?
我可以:
- 在表中,只需创建一个
FilterGenerator。这会管用,但不是很好。例如,如果其他组件想要使用FilterGenerator,会发生什么new
- 返回xml配置,以“手动”按正确顺序创建实例。这可能会起作用(如果我没记错的话),但是根据xml文件中元素的顺序创建实例对我来说不是很好
- 通过在代码中使用ApplicationContext.getBean()使用“编程注入”。这可能比上述替代方案更糟糕
@Component
@Scope("session")
public class SampleAppMainTable extends FilteringTable {
@Inject
private SampleAppMainTableContainer sampleAppMainTableContainer;
@Inject
private SampleAppService sampleAppService;
@Inject
private SampleAppMainTableFilterGenerator sampleAppMainTableFilterGenerator;
public SampleAppMainTable() {
//...setting up the table
}
@PostConstruct
public void PostConstruct() throws GeneralSecurityException {
addMainTableItems();
setupMainTable();
}
public void setupMainTable() {
this.setFilterGenerator(sampleAppMainTableFilterGenerator);
sampleAppMainTableFilterGenerator.getCustomFilterComponent("Sample Id");
this.setContainerDataSource(sampleAppMainTableContainer);
}
public void addMainTableItems() {
sampleAppMainTableContainer.addItemsToContainer(sampleAppService.getAllSamples());
}
}
容器
@Component
@Scope("prototype")
public class SampleAppMainTableContainer extends IndexedContainer {
public void addItemsToContainer(List<Sample> samples) {
// adding items to the container...
}
public Map<String, List<String>> getDistinctProperties() {
// extracting distinct items from the table...
}
}
@组件
@范围(“原型”)
公共类SampleAppMainTableContainer扩展IndexedContainer{
公共void addItemsToContainer(列出示例){
//正在将项目添加到容器。。。
}
公共地图getDistinctProperties(){
//正在从表中提取不同的项。。。
}
}
过滤器发生器
@Component
@Scope("session")
public class SampleAppMainTableFilterGenerator implements FilterGenerator {
@Inject
SampleAppMainTableContainer sampleAppMainTableContainer;
private List<String> aList = null;
@Override
public AbstractField<?> getCustomFilterComponent(Object propertyId) {
Map<String, List<String>> map = new HashMap<String, List<String>>();
map = sampleAppMainTableContainer.getDistinctProperties();
if (propertyId.equals("Sample Id")) {
ComboBox sampleIdCB = new ComboBox();
BeanItemContainer<String> dataList = new BeanItemContainer<String>(String.class);
List<String> aList = map.get("Sample Id");
dataList.addAll(aList);
sampleIdCB.setContainerDataSource(dataList);
sampleIdCB.setImmediate(true);
return sampleIdCB;
}
return null;
}
// other overridden methods needed...
}
@组件
@范围(“会议”)
公共类SampleAppMainTableFilterGenerator实现FilterGenerator{
@注入
SampleAppMainTableContainer SampleAppMainTableContainer;
私有列表=空;
@凌驾
公共抽象字段getCustomFilterComponent(对象属性ID){
Map Map=newhashmap();
map=sampleAppMainTableContainer.getDistinctProperties();
if(propertyId.equals(“样本Id”)){
ComboBox sampleIdCB=新ComboBox();
BeanItemContainer数据列表=新的BeanItemContainer(String.class);
List aList=map.get(“示例Id”);
dataList.addAll(列表);
sampleIdCB.setContainerDataSource(数据列表);
sampleIdCB.setImmediate(true);
返回样本Cb;
}
返回null;
}
//需要其他重写的方法。。。
}
我认为您的问题在于在注入阶段处理逻辑。您应该等到所有设置完成后再进行处理。您可以通过将处理逻辑从构造函数移动到初始化方法并用@Inject标记该方法来完成类似的操作。根据定义,注入是在方法上最后完成的,即在注入程序调用该方法时,所有字段都被注入。您的问题不只是因为您的过滤器生成器是有状态的,在那里它应该是无状态的吗?谢谢您的回复!我不完全明白你说的无国籍是什么意思。我的FilterGenerator类只是一个实现(Vaadin插件)FilterGenerator的简单类。它所做的是@Override一对方法,这些方法生成我的表中所需的过滤器。我的问题与容器在创建FilterGenerator时没有完全初始化有关。如果我在Table类中创建一个新的FilterGenerator(container)
,一切都会很顺利。我发现很难从您的描述中理解您的设置。你能提供一些代码片段来说明你在哪里做什么吗?我对Vaadin不太熟悉,但从你的描述来看,听起来你在创建一个保存状态的过滤器(它调用某个方法一次并缓存结果),而我想,is应该在需要时始终调用该方法。你自己实现了这个过滤器吗?你只说过滤器发电机。。。您确定两次都注入了相同的容器实例吗?根据您使用的注入框架,您需要显式配置是否为e创建新实例