Я использую 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);" Почему?
========================ОБНОВЛЕНИЕ======================== =====
Я знаю, что инъекция сеттера или инъекция конструктора работает.




Вы можете попробовать это.
@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 Это что-то связанное с тем, как Spring определяет зависимости между bean-компонентами. Ваша текущая реализация не подразумевает, что зависимость существует.
Во-первых, вам нужно получить пружинный контейнер ApplicationContextAware попробовать
ApplicationContext.getBean(EagleRestClient.class)
Вы не должны использовать ApplicationContext или BeanFactory напрямую в своем коде, это обычно указывает на то, что вы делаете что-то не так.
Почему? Есть ошибка?
Вы должны использовать внедрение зависимостей, а также тот факт, что вы не хотите привязывать код своего приложения к Spring с помощью ApplicationContext для поиска bean-компонентов.
Потому что порядок загрузки 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 сначала создаст клиент отдыха, а затем службу орла.
Вы можете обнаружить, что в некоторых сборках это работает, а в других — нет из-за нетерпеливого создания экземпляров
@Beanметодов в@Configurationклассах. Используйте ответ, предоставленный @DKD, чтобы убедиться, что ваш метод @Bean получает свои сконструированные зависимости в качестве аргументов конструктора, или полагайтесь на хаки, такие как@Lazy, чтобы предотвратить нетерпеливое создание экземпляров.