我有一些组件,应该在运行时注入它们。基本流程的工作原理如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 documentation,the Tapestry mailing list或other mailing lists.
中一样我对Tapestry的经验也不是很好,但有没有其他方法可以解决这个问题?例如注入IoC container
本身并要求它根据其限定符或类名返回我的组件?
答案 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>