0

PicoContainer 似乎表明它支持 JSR-330@Inject@Named. (不,这个其他问题似乎没有帮助,因为它没有解决 PicoContainer 站点说已添加对 JSR-330 的一些支持这一事实。)

我像这样向容器中添加一些东西:

container.addComponent(Foo.class);
container.addComponent("myBar", new MySpecialBar());
container.addComponent("decoy", new SomeOtherBar());

我用以下标记构造函数参数@Named

public class Foo(@Named("myBar") Bar bar) { ...

但是当我尝试获取Foo实例时,PicoContainer 抱怨它有太多Bar实例可供选择。

问题 1:如何让 PicoContainer@Named用于构造函数注入?

然后我尝试在里面使用字段注入Foo.java

@Inject
@Named("myBar")
Bar bar;

那也行不通。

问题 2:如何让 PicoContainer 使用@Inject@Named用于构造函数注入?

还是PicoContainer 新闻页面错了,根本没有任何 PicoContainer 2.x 对 JSR-330 的支持?

4

1 回答 1

1

看起来我是 stackoverflow 上唯一回答 pico 问题的人,但我不是 pico 团队成员,所以对于最终答案,您可能需要访问他们的邮件列表 :)

在查看框架源代码(2.10 ... 2.15)时,我看不到对 javax.inject.Named 的任何支持,并且 @Inject 被支持为 pico 注释,而不是 javax.inject.Inject

至于解决模棱两可的依赖关系,pico 提供了几种方法:http ://picocontainer.codehaus.org/ambiguous-injectable-help.html (使用参数名称,恕我直言有点奇怪,但对你来说可能没问题)和http://picocontainer .codehaus.org/disambiguation.html(使用 Parameter 对象——还不错,但是很冗长,另一个使用 Guice 中的绑定注释,恕我直言更奇怪)如果以上都不适合您,您可以采用 Parameter 对象的想法和让你的消歧小适配器,恕我直言,看起来更干净

    class DisambiguationAdapter<T> extends AbstractAdapter<T> {

    private final Object[] params;

    public DisambiguationAdapter(Object componentKey, Class<T> componentImplementation, Object... params) {
        super(componentKey, componentImplementation);
        this.params = params;
    }
    // the idea is to make child container that overrides ambiguos deps using the parameters hints
    @Override
    public T getComponentInstance(PicoContainer container, Type into) throws PicoCompositionException {
        MutablePicoContainer tmpContainer = new DefaultPicoContainer(container);
        tmpContainer.addComponent(getComponentKey(), getComponentImplementation());
        for (Object param : params) {
            tmpContainer.addComponent(container.getComponent(param));
        }

        T instance = tmpContainer.getComponent(getComponentImplementation());
        tmpContainer.dispose();
        return instance;
    }

    @Override
    public void verify(PicoContainer container) throws PicoCompositionException {
        for (Object param : params) {
            if(container.getComponent(param) == null) {
                throw new PicoCompositionException("Can't resolve param-key=" + param + " to satisfy dependencies for " + getDescriptor());
            }
        }
    }

    @Override
    public String getDescriptor() {
        return getComponentImplementation().getCanonicalName();
    }
}

然后您声明此方法以添加需要模棱两可的 deps 的组件:

    public void register(Object key, Class<?> component, Object... params) {
    container.addAdapter(new DisambiguationAdapter<>(key, component, params));
}

然后你像这样使用它:

// constructor for some class requiring ambig deps
public ProfileFinder(/* ambig param */ ProfileDao dao, /* any other params */ Param1 param1, Param1 param2)......

// container composition
// hint key, impl class
c.addComponent(ProfileDaoSelector.SLAVE, jdbi.onDemand(ProfileDao.class));
c.addComponent(ProfileDaoSelector.MASTER, jdbiMaster.onDemand(ProfileDao.class));
// impl class, hint keys array
c.register(ProfileService.class, new Object[] {ProfileDaoSelector.MASTER});
c.register(ProfileFinder.class, new Object[] {ProfileDaoSelector.SLAVE});
于 2015-01-16T10:09:20.110 回答