工厂实例化组件中的依赖注入

时间:2013-07-31 09:20:40

标签: java dependency-injection seam factory seam2

有两个类FooBar,在Baz支持的应用程序中实现了一些接口Seam 2.2.2。我正在尝试使用这两个类中的一个来有条件地实现Baz类型的组件。为此,我创建了一个工厂组件BazFactory,使用BazFoo实例化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();
    }
}

问题是在这种情况下,依赖关系不会注入实例化的类中。我设计的唯一解决方法是将FooBar声明为组件:

@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实现创建一个组件。因此,这种解决方法对我来说看起来很难看。如果有上述依赖注入问题的解决方案,我宁愿使用第一种方式。

有没有办法将依赖项注入工厂实例化组件?

1 个答案:

答案 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

通过这种方式,您可以返回所需的实现类型,具体取决于您在工厂类中收到的输入。

由于