PicoContainer JSR-330 @ Названа поддержка?

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 неправильная, и просто отсутствует поддержка PSRContainer 2.x для JSR-330?

1 ответ

Похоже, я единственный человек в stackru, который отвечает на вопросы по пико, но я не являюсь членом команды пико, поэтому для окончательного ответа вам, возможно, потребуется посетить их список рассылки:)

При просмотре исходных текстов фреймворка (2.10 ... 2.15) я не вижу никакой поддержки javax.inject.Named, а @Inject поддерживается как пико-аннотация, а не как javax.inject.Inject.

Что касается решения неоднозначных зависимостей, pico предлагает несколько способов: http://picocontainer.codehaus.org/ambiguous-injectable-help.html (используя имена параметров, IMHO, немного странно, но это может быть хорошо для вас) и 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();
    }
}

затем вы объявляете этот метод для добавления компонентов, которые требуют неоднозначных действий:

    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});
Другие вопросы по тегам