spring-bootのEnvironmentPostProcessor
を実装する事でEnvironment
の初期化処理に後処理を追加可能になる。これでプロパティの初期化をカスタマイズできる。大抵のケースでExternalized Configurationを利用すればプロパティは問題無いが、それでは機能不足する場合などに利用する。
以下の例では実行時に現在時刻(EnvironmentPostProcessor
実行時点)のプロパティを追加する。
plugins { id 'org.springframework.boot' version '2.4.3' id 'io.spring.dependency-management' version '1.0.11.RELEASE' id 'java' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '15' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' } test { useJUnitPlatform() }
import java.time.LocalDateTime; import java.util.Map; import org.apache.commons.logging.Log; import org.springframework.boot.ConfigurableBootstrapContext; import org.springframework.boot.SpringApplication; import org.springframework.boot.env.EnvironmentPostProcessor; import org.springframework.boot.logging.DeferredLogFactory; import org.springframework.core.Ordered; import org.springframework.core.annotation.Order; import org.springframework.core.env.ConfigurableEnvironment; import org.springframework.core.env.MapPropertySource; import org.springframework.core.env.PropertySource; @Order(Ordered.LOWEST_PRECEDENCE) public class MyEnvPostProcessor implements EnvironmentPostProcessor { public MyEnvPostProcessor(DeferredLogFactory factory, Log log, ConfigurableBootstrapContext context) { log.info("log MyEnvPostProcessor"); } @Override public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) { PropertySource<?> property = new MapPropertySource("myEnvPost", Map.of("current.local-date-time", LocalDateTime.now().toString())); environment.getPropertySources().addLast(property); } }
current.local-date-time
という名前のプロパティを追加している。
@Order
は任意だが用途を考えると基本的には低優先度を設定すると思われる。
また、任意でコンストラクタにはDeferredLogFactory
, org.apache.commons.logging.Log
, ConfigurableBootstrapContext
を指定できる。
次にこの実装クラスをMETA-INF/spring.factories
で登録する。src/main/resources/META-INF/spring.factories
を作成する。
org.springframework.boot.env.EnvironmentPostProcessor=kagaimhoge.sample.MyEnvPostProcessor
最後に動作確認用のMain
クラス。
import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class Main implements CommandLineRunner { public static void main(String[] args) { SpringApplication.run(Main.class, args); } @Value("${current.local-date-time}") String now; @Override public void run(String... args) throws Exception { System.out.println(now); } }