Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/28.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何设计依赖于实例创建顺序的类的DI_Java_Oop_Design Patterns_Vaadin_Vaadin7 - Fatal编程技术网

Java 如何设计依赖于实例创建顺序的类的DI

Java 如何设计依赖于实例创建顺序的类的DI,java,oop,design-patterns,vaadin,vaadin7,Java,Oop,Design Patterns,Vaadin,Vaadin7,这感觉像是一个相当标准的问题,以前可能有人问过,但我发现很难找到,因为很难用语言来定义。所以,如果这是一个重复,继续和重定向我 我正在使用Vaadin来构建这个web应用程序,但这对手头的问题不重要,除非有更好的方法通过Vaadin魔法来解决这个问题 我有三门课: 桌子 过滤器发生器 容器 我的“设计”如下所示: 容器在其构造函数中向自身添加一些属性(列标题) FilterGenerator@注入容器(以便使用容器的getDistinct()方法从容器中获取不同的项-以便在过滤器的组合框中

这感觉像是一个相当标准的问题,以前可能有人问过,但我发现很难找到,因为很难用语言来定义。所以,如果这是一个重复,继续和重定向我

我正在使用Vaadin来构建这个web应用程序,但这对手头的问题不重要,除非有更好的方法通过Vaadin魔法来解决这个问题

我有三门课:
  • 桌子
  • 过滤器发生器
  • 容器
我的“设计”如下所示:
  • 容器在其构造函数中向自身添加一些属性(列标题)
  • FilterGenerator@注入容器(以便使用容器的getDistinct()方法从容器中获取不同的项-以便在过滤器的组合框中很好地显示它们)
  • @注入FilterGenerator(以便表.setFilterGenerator(FilterGenerator))
  • @注入容器并调用containers addItems()方法将项添加到容器中
  • 表将容器添加为数据源
会发生什么? 我现在应该有一个在列标题中有一个组合框的表,它显示了要过滤的不同值

我得到的是一个列标题中有ComboBox的表,ComboBox中没有任何内容,因为ComboBox中没有任何项目

这并不奇怪,因为当FilterGenerator调用Containers getDistinct()方法时,它会返回一个空的
映射,因为在FilterGenerator中@Inject时,表还没有调用Containers addItems()方法,所以此时容器将是空的

问题 如果我想让一个组件(FilterTable)从第二个组件(容器)中获取一些东西,当第三个组件(表)正在@Inject注入上述两个组件时,我应该如何设计这个应用程序?当第一个组件(FilterGenerator)启动时,第二个组件(容器)已经初始化是至关重要的从中获取一些信息?

我可以:

  • 在表中,只需创建一个
    new
    FilterGenerator。这会管用,但不是很好。例如,如果其他组件想要使用FilterGenerator,会发生什么

  • 返回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创建新实例