我正在编写一个将由spring-boot项目使用的库。我想向引导项目的SpringEnvironment
中注入一个我从Internet上获取的资源。
我尝试了以下
@Configuration
public class MyCustomConfiguration {
@Bean
BeanDefinedAbove above() { /* do some work */ }
@Bean
@ConditionalOnBean(BeanDefinedAbove.class)
SmartInitializingSingleton propertySourceSetting(ConfigurableEnvironment env, BeanDefinedAbove bean) {
return () -> {
PropertySource source = bean.getPropertySourceDownloadedFromTheInternet();
env.getPropertySources().addFirst(source);
}
}
}
在我的客户项目中,当我调试此代码时,发生的事情是两者之一:
above()
被称为@Service
或@Controller
被称为propertySourceSetting(...)
被称为OR
@Service
或@Controller
被称为above()
被称为propertySourceSetting(...)
被称为取决于我的客户是否依赖我的BeanDefinedAbove
bean,这与@Service
一样正常,这取决于在above()
中创建的bean。
我还将班级的FQDN添加到了EnableAutoConfiguration
的{{1}}中。
因此,如何确保在用户的META-INF/spring.factories
和propertySourceSetting(..)
之前调用@Service
中的逻辑
答案 0 :(得分:0)
我将为您提供三种选择。
选项1:(这是一种错误的方法,但需要快速解决)
向两个Bean添加@Lazy(false)批注。 Spring会急切地创建这两个bean,它们可能会在其他bean之前创建。
为什么这不好? 这不能确保顺序。 Spring根据依赖关系和其他一些条件决定创建顺序。这就是为什么它将“可能”起作用的原因:)
选项2:创建一个主类来引导Spring Boot初始化(启动Spring Boot的旧方法)。
public static void main(String[] args) throws Exception {
SpringApplication application = new SpringApplication(MyApplication.class);
// ... add property source here before start
application.run(args)
}
您还需要在Spring Boot清单中指定主类,例如:https://www.baeldung.com/spring-boot-main-class
在该主类中,您可以添加属性源,就像这样:
SomeClassThatRetrievesProperties propRetriever = new SomeClassThatRetrievesProperties ();
Map<String,String> properties = propRetriever.getAllPropertiesAsMap();
application.setDefaultProperties(properties);
选项3 :通过扩展WebApplicationContext并覆盖getSpecificConfigurations()方法来创建CustomApplicationContext。
这样,您将拥有完全的控制权,但是我们知道您可能会破坏一些重要的东西。