在创建其他bean之前如何在SPRING中注入额外的属性源?

时间:2018-10-09 14:36:00

标签: java spring spring-boot

我正在编写一个将由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);
    }
  }
}

在我的客户项目中,当我调试此代码时,发生的事情是两者之一:

  1. above()被称为
  2. 用户的@Service@Controller被称为
  3. propertySourceSetting(...)被称为

OR

  1. 用户的@Service@Controller被称为
  2. above()被称为
  3. propertySourceSetting(...)被称为

取决于我的客户是否依赖我的BeanDefinedAbove bean,这与@Service一样正常,这取决于在above()中创建的bean。

我还将班级的FQDN添加到了EnableAutoConfiguration的{​​{1}}中。

因此,如何确保在用户的META-INF/spring.factoriespropertySourceSetting(..)之前调用@Service中的逻辑

1 个答案:

答案 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。

这样,您将拥有完全的控制权,但是我们知道您可能会破坏一些重要的东西。