Как Micronaut внедряет только аннотацию @Inject?

#java #dependency-injection #javabeans #inject #micronaut

#java #внедрение зависимостей #javabeans #внедрять #micronaut

Вопрос:

Я использую @Inject в проекте Micronaut для выполнения внедрения зависимостей через свойства. Я начал с ServiceA, который изначально внедряет ServiceB, и у ServiceB есть куча собственных зависимостей, кажется, все работает гармонично.

 @Singleton
public class ServiceA {
    @Inject
    private ServiceB serviceB;

    @Inject
    private ServiceC serviceC;
    
    ...
}
  
 public class ServiceB {
    @Inject
    private ServiceD serviceD;

    ...
}
  
 public class ServiceC {
    ...
}
  

Проблема возникла, когда я добавил ServiceC (который не имеет никаких зависимостей) в ServiceA, приложение выдает следующее исключение во время выполнения.

 Error processing bean [Definition: ...] method definition [...]: Failed to inject value for field [serviceC] of class: ServiceA

Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [ServiceC] exists.
  

Исправление, которое заставляет код компилироваться и выполняться снова, заключается в добавлении @Singleton в ServiceC. На данный момент единственное различие между ServiceB и ServiceC заключается в том, что у ServiceB есть @Inject для свойства класса, тогда как у SerivceC есть аннотация @Singleton для всего класса.

Поэтому мои вопросы таковы: как Micronaut понимает, как вводить зависимости только с помощью аннотации @Inject в свойствах без каких-либо аннотаций уровня класса, таких как @Singleton, каковы реальные правила / иерархия для указания аннотаций в Micronaut.

Спасибо

Комментарии:

1. Вероятно, потому, что Micronaut определяет, что класс, в котором есть поле / метод, аннотированный @Inject , неявно является компонентом. — Я бы предложил предпочесть внедрение конструктора, а не внедрение поля.

2. Да, согласен с предпочтением внедрения конструктора, но я думаю, что вопрос остается тем же, если бы к классу, который является зависимостью от другого класса, не применялась аннотация. Но я не уверен в неявном поведении, которое превращает целый класс в компонент

3. Aa Я сказал: контейнер CDI в любом случае должен анализировать аннотации и, таким образом, вероятно, определяет, что все классы, имеющие поле или метод, аннотированный @Inject , сами являются компонентами.

4. «контейнер CDI все равно должен анализировать аннотации» — это не совсем так. Предполагая, что вы имеете в виду контейнер для внедрения зависимостей (DI), контейнер не анализирует аннотации. Мы выполняем обработку аннотации DI во время компиляции, до того, как экземпляр контейнера DI существует.