Почему при использовании @Autowired в @Configuration в Spring иногда не удавалось?

Я использую Spring Boot с комиссионным сервером, и у меня есть два класса @Configuration с двумя методами генерации bean-компонентов, и код выглядит следующим образом:

@Configuration
public class EagleBeanCreator {

    @Bean(destroyMethod = "destroy")
    public EagleRestClient build() {
        EagleRestClient client = new EagleRestClient();
        // some set values code
        return client;
    }
}

И еще один:

@Configuration
public class EagleServiceBuilder {

    @Autowired
    private EagleRestClient eagleProxy;

    @Bean
    public EagleService eagleService() {
        EagleService service = new EagleService();
        System.out.println(eagleProxy);
        service.setEagleProxy(eagleProxy);
        return service;
    }
}

Но когда я запускаю spring-boot:run, он выводит значение null для "System.out.println(eagleProxy);" Почему?

========================ОБНОВЛЕНИЕ======================== =====

Я знаю, что инъекция сеттера или инъекция конструктора работает.

Вы можете обнаружить, что в некоторых сборках это работает, а в других — нет из-за нетерпеливого создания экземпляров @Bean методов в @Configuration классах. Используйте ответ, предоставленный @DKD, чтобы убедиться, что ваш метод @Bean получает свои сконструированные зависимости в качестве аргументов конструктора, или полагайтесь на хаки, такие как @Lazy, чтобы предотвратить нетерпеливое создание экземпляров.

Andy Brown 15.05.2019 10:29
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
1
564
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Вы можете попробовать это.

@Configuration
public class EagleServiceBuilder {

    @Bean
    public EagleService eagleService(EagleRestClient eagleProxy) {
        EagleService service = new EagleService();
        System.out.println(eagleProxy);
        service.setEagleProxy(eagleProxy);
        return service;
    }
}

Я предполагаю, что способ, которым вы в настоящее время реализуете, не указывает на зависимость между EagleService и EagleRestClient. Таким образом, ваша текущая реализация приводит к случайному порядку инициализации между двумя компонентами. Модифицированная версия сообщает Spring: «Эй, мой EagleService зависит от EagleRestClient. Пожалуйста, инициализируйте EagleRestClient перед EagleService.

Спасибо. Я действительно знаю, что это работает, но я хочу знать, почему мой код не работает :(

Gao 15.05.2019 04:34

@Gao Это что-то связанное с тем, как Spring определяет зависимости между bean-компонентами. Ваша текущая реализация не подразумевает, что зависимость существует.

DKD 15.05.2019 05:20

Во-первых, вам нужно получить пружинный контейнер ApplicationContextAware попробовать

ApplicationContext.getBean(EagleRestClient.class)

Вы не должны использовать ApplicationContext или BeanFactory напрямую в своем коде, это обычно указывает на то, что вы делаете что-то не так.

M. Deinum 15.05.2019 07:38

Почему? Есть ошибка?

周仲清 17.05.2019 03:41

Вы должны использовать внедрение зависимостей, а также тот факт, что вы не хотите привязывать код своего приложения к Spring с помощью ApplicationContext для поиска bean-компонентов.

M. Deinum 20.05.2019 07:42
Ответ принят как подходящий

Потому что порядок загрузки EagleBeanCreator и EagleServiceBuilder не определен. Вы можете использовать @Order или @ConditionalOnClass, чтобы сначала инициализировать EagleBeanCreator.

Потому что bean-компонент @Configuration инициализируется на той же фазе жизненного цикла bean-компонента. Я не помню их четко, но что-то вроде:

Configurations -> Components -> Services

С bean-компонентами в одной фазе, если они зависят друг от друга, вы должны объявить порядок загрузки каким-то @Conditional или @Order

Добавьте аннотацию @DependsOn("eagleRestClient") к определению EagleService.

@DependsOn("eagleRestClient")
@Bean
 public EagleService eagleService() {
       EagleService service = new 
       EagleService();
       System.out.println(eagleProxy);
       service.setEagleProxy(eagleProxy);
        return service;
  }

Затем Spring сначала создаст клиент отдыха, а затем службу орла.

Другие вопросы по теме