Apache Tapestry:定义要在运行时注入的组件

时间:2016-03-22 15:09:09

标签: java inversion-of-control tapestry

我有一些组件,应该在运行时注入它们。基本流程的工作原理如this article.中所述。但是,文章显示了一个非常简单的示例,我想对其进行扩展。

请考虑以下事项:
加载网站的索引页面时,菜单组件会在类路径上可用时动态添加。我能够在运行时找到组件的所有完全限定的类名,但是无法实例化它们,因为它们应该由Tapestry IOC Container实例化。

e.g。而不是以下

@InjectComponent
private Menu menu;

我想通过代码实例化它。这样,我可以有一个方法根据其参数返回正确的组件:

public Object getMenuComponent(String fullyQualifiedClassName) {
    // Ask the Tapestry IOC Container to retrieve the component based on its classname or library name
    return new Menu();
}

之后我可以通过.tml文件中的委托导入组件。

<t:delegate to="getMenuComponent()"/>

new Menu();当然是一个静态占位符,但是当然我也没有用,因为那时我正在实例化一个由IOC container管理的类。

我已经阅读了几个主题和文章,说Tapestry有一个静态结构,这是不允许的。与the documentationthe Tapestry mailing listother mailing lists.

中一样

我对Tapestry的经验也不是很好,但有没有其他方法可以解决这个问题?例如注入IoC container本身并要求它根据其限定符或类名返回我的组件?

1 个答案:

答案 0 :(得分:0)

找到了我的问题的解决方案。 Tapestry加载类,因此它们已在容器中可用。我只是不知道如何让他们离开那里。因此,我没有尝试返回组件,而是解析所有可用页面,加载其类并检查注释。当我得到我需要的那些时,我会返回他们的页面名称,可以在.tml中使用。然后在.tml文件中,我可以使用现有组件为我加载页面。

这是控制器中的逻辑:

public List<String> getPages() {
    List<String> result = new ArrayList<String>();
    for (final String pageName : this.componentClassResolver.getPageNames()) {
        String className = this.componentClassResolver.resolvePageNameToClassName(pageName);
        Class clazz = loadClass(className);
        if (clazz.isAnnotationPresent(MainPage.class)) {
            result.add(pageName);
        }
    }
    return result;
}

对应.tml

<li t:type="loop" source="pages" value="mainPage">
    <t:pagelink page="${mainPage}">${mainPage}</t:pagelink>
</li>