2016-10-24 6 views
0

Я использую WELD SE в автономном проекте java, который, казалось, работал нормально, пока я не начал использовать производителей.CDI (Weld SE) не впрыскивает внутренние зависимости при использовании метода производителя

Метод изготовления работает - контейнер использует его, но никогда не вводит внутренние зависимости производимого компонента. Когда я удаляю производителя, он работает нормально. Я не могу найти причину даже после длительного поиска в спецификации и в Google.

Пример Производитель:

@ApplicationScoped 
public class LaminaValidadorProducer { 

    private static final String XSD_PATH = getConfig("processador.xsd.path"); 
    private static final Map<VersaoLamina,String> XSD_PER_VERSION = new HashMap<>(); 
    static { 
     XSD_PER_VERSION.put(VersaoLamina.V1, getConfig("processador.lamina.xsd.file")); 
     XSD_PER_VERSION.put(VersaoLamina.V2, getConfig("processador.laminav2.xsd.file"));   
    } 

    @Produces 
    public LaminaValidador buildValidador() { 
     return new LaminaValidador(XSD_PATH, XSD_PER_VERSION); 
    } 
} 

LaminaValidador вводят, как правило, но его внутренней атрибуты (отмеченные @Inject) не впрыскивают. В проекте есть beans.xml с bean-discovery-mode = "all".

Любые подсказки о том, что происходит?

ответ

1

Это не только вопрос SE, и это действительно желаемое/ожидаемое поведение CDI.

Причина в том, что обычно, если у вас нет производителей, CDI создает для вас классы bean (путем вызова конструктора no-args или одного с инъекциями), а затем разрешает точки вставки в компоненте (и делает некоторые другие вещи, см. спецификацию). . вы оставите управление жизненным циклом в контейнере CDI.

С другой стороны, с помощью продюсера, как правило, способ создания боб из класса, где:

  • вы не можете контролировать жизненный цикл самостоятельно, вы, например, EntityManager
  • вы межтереть с другими системами, и они имеют сложную инициализацию
  • вам нужно сделать некоторые проверки для внешней конфигурации перед вызовом некоего конструктора
  • или вы, возможно, хотите боб для примитивного типа (INT)
  • и многие многие другие случаи использования

Теперь это означает, что вы ответственны за создание компонента. И это включает любые поля внутри. Контейнер просто берет производителя как способ создания полноразмерного компонента и предполагает, что вы позаботились или что требуется инициализация.

Теперь, исходя из вашего вопроса, я считаю, что вам нужно разрешение точки впрыска внутрь. Нет простого способа, если таковые имеются, «принудительно выполнить» разрешение вручную из-за статического характера CDI (и других, более сложных причин). Следовательно, я бы предложил использовать другой подход и использовать конструктор-инъектор или, возможно, методы инициализации? Если вы предоставите больше информации, я могу помочь.

+0

Позор мне - основной материал, о котором я не знал. Спасибо. Мне никогда не приходилось создавать производителя бобов с внутренними зависимостями, отмеченными с помощью @Inject, поэтому он всегда работал - в моей голове, как только вы передали аргументы конструктору, CDI продолжит вводить атрибуты, помеченные явно с помощью Inject. Это было бы трудно реализовать, поэтому я считаю, что поведение структуры правильное. –

+0

Я мог бы решить проблему, обернув эту карту (см. Мой пост) в другом классе (без дополнительных зависимостей). Итак, я создал производителя этого класса (который отлично работает), а затем @ ввел его в конструктор LaminaValidador через конструктор. Теперь работает как шарм. Еще раз спасибо. –

+0

Рад, что я мог помочь!BTW-упаковка с другим классом действительно работает, но вы также можете создать метод-производитель, который даст вам карту (и в теле метода вы инициализируете его, как хотите). Такой метод продления может находиться в том же классе, который у вас есть. Затем вы можете вставлять карту в любом месте, включая конструктор вашего класса LaminaValidador' (например, [с использованием вставки конструктора] (http://docs.jboss.org/cdi/spec/1.2/cdi-spec.html#declaring_bean_constructor)) , – Siliarus