有两个类Foo
和Bar
,在Baz
支持的应用程序中实现了一些接口Seam 2.2.2
。我正在尝试使用这两个类中的一个来有条件地实现Baz
类型的组件。为此,我创建了一个工厂组件BazFactory
,使用Baz
或Foo
实例化Bar
,具体取决于implClassName
字段的值:
public interface Baz {...}
public class Foo implements Baz {
@In
String injectedValue1;
...
}
public class Bar implements Baz {
@In
String injectedValue2;
...
}
@Name("bazFactory")
@Scope(value = ScopeType.SESSION)
public class BazFactory {
private String implClassName;
public void setImplClassName(String implClassName) {
this.implClassName = implClassName;
}
@Factory(value="baz", scope = ScopeType.SESSION)
public Baz getBazImpl() throws Exception {
Class.forName(this.implClassName).newInstance();
}
}
问题是在这种情况下,依赖关系不会注入实例化的类中。我设计的唯一解决方法是将Foo
和Bar
声明为组件:
@Name("foo")
@Scope(ScopeType.CONVERSATION)
public class Foo implements Baz {
@In
String injectedValue1;
...
}
@Name("bar")
@Scope(ScopeType.CONVERSATION)
public class Bar implements Baz {
@In
String injectedValue2;
...
}
@Name("bazFactory")
@Scope(value = ScopeType.SESSION)
public class BazFactory {
private String implComponentName;
public void setImplComponentName(String implComponentName) {
this.implComponentName = implComponentName;
}
@Factory(value="baz", scope = ScopeType.SESSION)
public Baz getBazImpl() {
return (Baz) Component.getInstance(this.implComponentName);
}
}
然而,在这种情况下,范围类型很混乱。例如,在声明实例化此组件的工厂方法的声明中,如何在其声明中具有@Scope(ScopeType.CONVERSATION)
的组件和scope = ScopeType.SESSION
的范围(如上例所示)?此外,解决方法涉及为每个Baz
实现创建一个组件。因此,这种解决方法对我来说看起来很难看。如果有上述依赖注入问题的解决方案,我宁愿使用第一种方式。
有没有办法将依赖项注入工厂实例化组件?
答案 0 :(得分:0)
你可以用更简单的方式实现同样的目标。 在您的工厂中,不应使用Class.forName()。newInstance()来创建新实例。
另一方面,在上下文文件中,您可以使用
之类的bean<bean id="bar" class="com.techidiocy.Bar"/>
<bean id="foo" class="com.techidiocy.Foo"/>
假设: Bar和Foo的必需属性将自动装配或手动注入。
在你的工厂中,你可以通过传递bean名称来加载这个上下文文件并从中获取bean,因为你已经在你的工厂中得到了它。
ApplicationContext context = new ClassPathXmlApplicationContext
("classpath:context.xml");
return context.getBean(implClassName);//implClassName is the input that you are receiving in factory
通过这种方式,您可以返回所需的实现类型,具体取决于您在工厂类中收到的输入。
由于