Внедренная в cdi зависимость разрешена в ноль в бине, созданном методом продюсера - PullRequest
0 голосов
/ 17 декабря 2018

Я пытаюсь внедрить зависимость в бин (Some/OtherImpl), помеченный @Named, но зависимость (configurationService) всегда разрешается до null (Resources#getConfiguratioService не вызывается), когда новыйЭкземпляр этого компонента создается в контроллере (MyCtrl) с использованием метода его производителя.

Однако, если я пытаюсь внедрить ConfigurationService непосредственно в контроллер, метод Resources#getConfiguratioService запускается и создает новый экземпляр * 1009.* который вводится в контроллер.

Вот как это выглядит

public class Resources() {
  @Produces
  public ConfigurationService getConfigurationService() {
      return new ConfigurationService(Constants.CONFIG);
  }
}

public abstract class MyAbstractClass {

  @Inject
  private transient ConfigurationService configurationService; // getter+setter

}

@Named
public class SomeImpl extends MyAbstractClass implements Serializable {
  // ...
}

@Named
public class OtherImpl extends MyAbstractClass implements Serializable {
  // ...
}

@Named
@ViewScoped
public class MyCtrl {

  @Inject
  private SomeImpl someImpl;

  @Produces
  public SomeImpl getSomeImpl() {
    return new SomeImpl(MyStringParam);
  }

}

Подскажите, пожалуйста, что я здесь не так делаю?Есть ли способ как это исправить?Каждый намек будет оценен.Спасибо заранее!

1 Ответ

0 голосов
/ 18 декабря 2018

Проблема здесь в том, что вы создаете экземпляр SomeImpl 'вручную' с помощью ключевого слова new. В этом случае вы создаете / предоставляете объект, инъекция не происходит, иВы передаете этот объект в CDI.С этого момента любая точка внедрения типа SomeImpl и с квалификаторами по умолчанию будет использовать вашего производителя для создания компонента.Производители часто являются способом превращения не-CDI-объектов в bean-компонент CDI, но имеют ограничение, заключающееся в том, что внедрение не происходит;обратите внимание, что это ограничение иногда является реальным преимуществом, потому что некоторые другие фреймворки могут разрешать внедрение или иным образом создавать экземпляры и изменять экземпляр, и вы просто передаете его в CDI (пример - интеграция с EJB).

КакВ качестве решения удалите производителя и дайте CDI создать экземпляр самостоятельно. CDI вызовет конструктор без аргументов (или конструктор с вводимыми параметрами, если таковые имеются), чтобы создать экземпляр, а затем выполнить внедрение в этот новый объект.

С этого момента ваш код должен работать так, как вы ожидаете.

В редких случаях, когда вы не можете позволить CDI управлять всем жизненным циклом, и вам действительно нужно вручную создать экземпляр и по-прежнему внедрять в него, InjectionTargetFactory - это то, что вы ищете. Для этого требуется, но BeanManager.getInjectionTargetFactory() - это отправная точка, в которой вы нуждаетесь.

...