【发布时间】:2011-07-08 07:38:18
【问题描述】:
我想在我们的项目中引入 CDI(焊接),但现在手动构建的对象遇到了一些问题。
所以我们有一些实现IReport 接口的类,它们有一个应该被注入的字段。这在运行时为 null,因为所有这些类都是由类 ReportController 中的 ReportFactory 生成的。
private Map<String,Object> generateReport(ReportInfo ri, ...) {
// some input validation
IReport report = ReportControllerFactory.getReportInstance( ri.getClassName() );
// ...
}
我知道我可以将@Produces 注释与ReportControllerFactory 中的另一个自定义注释一起使用,但是在完成一些验证后,如何将@Inject 用于只能创建的变量, 里面一个方法?我将如何提交参数ri.getClassName()?对象ri 在构造ReportController 时是未知的。
非常感谢!
亲切的问候, 塞巴斯蒂安
2011 年 7 月 8 日 (10:00) 编辑:
ReportFactory 类:
public static IReport getReportInstance( String className ) throws ReportException {
IReport report = null;
try {
Class<?> clazz = Class.forName( className );
report = (IReport) clazz.newInstance();
}
catch ( Exception e ) { … }
return report;
}
编辑 2(选择正确的报告实施)
报表实例由一些从 JSF 前端到 ReportController 的路径选择。 ManagedBean 调用一个会话 bean,该会话 bean 有多种方法,具体取决于在何处按下了哪个按钮。所有这些方法都设置报告名称并调用更通用的方法sendOrGetReport。此方法从数据库中选择指定报告的唯一键,并决定是发送电子邮件还是立即发送报告。让我们假设它应该交付。
然后ReportController 开始发挥作用。他根据上述方法提供的唯一键和其他信息获取ReportInfo 对象,并调用ReportFactory 创建ri.getClassName() 类型的报告。
花哨,对吧?我认为整个部分可能需要一些重构。如果您没有看到任何容易的地方,我会跳过报告实现中的 @Inject 并对该资源进行 JDNI 查找。
【问题讨论】:
-
您是否尝试注入“报告”(这似乎很奇怪,因为您指出它只能在运行时构建)?或者你需要的是注入一个工厂(带有注入的依赖项)而不是使用静态方法?
-
是的,“报告”有一个带有@Inject 注释的字段。所以我必须以某种方式告诉 CDI 解决该注入。我编辑了我的问题并添加了工厂代码。
-
好的,但在这种情况下,由于您使用 clazz.newInstance() 创建 IReport bean,它无法获得注入的依赖项,对吗?我不知道你的 DI 框架,但你可能必须使用框架中的某种“injector”/“beanRepository”/“beanFactory”来创建注入依赖项的 bean,不是吗?
-
你能否用一些更明确的信息来更新你的问题,这些信息是关于你需要在运行时决定需要哪个 IReport 实现的标准?
-
谢谢,我做到了。相当复杂,但它可能会有所帮助。
标签: java factory factory-pattern cdi jboss-weld