SpringBootでDIコンテナにBean登録するといえば、@Bean
や@Component
がメインですが、それ以外の方法でBean登録をする方法を調べてみました!
結論
GenericApplicationContext
を使えばアノテーションに頼らずBean登録ができます!
実装例です。
@Configuration
public class SampleAutoConfiguration {
public SampleAutoConfiguration(GenericApplicationContext context) {
// Bean登録したいオブジェクトを生成
var restTemplate1 = new RestTemplateBuilder()
.rootUri("http://localhost:8080")
.build();
var restTemplate2 = new RestTemplateBuilder()
.rootUri("http://localhost:80")
.build();
// registerBeanで登録
context.registerBean("restTemplate1", RestTemplate.class, () -> restTemplate1);
context.registerBean("restTemplate2", RestTemplate.class, () -> restTemplate2);
}
}
使い所
同一クラスのBeanを大量に生成したい時に便利です!
例えば以下のようなにyamlでマップ(もしくはリスト)でRestTemplate生成のためのpropertyを定義し、それぞれのpropertyにあったRestTemplateを生成したい場合です。
sample-app:
rest-templates:
a:
root-uri: https://a.com
b:
root-uri: https://b.com
@Data
@ConfigurationProperties("sample-app")
public class RestTemplateProperties {
private Map<String, RestTemplateProperty> restTemplates;
@Data
public static class RestTemplateProperty {
private String rootUri;
}
}
Bean生成はこんな感じで1つのメソッドで完結します。
@Configuration
@EnableConfigurationProperties(RestTemplateProperties.class)
public class SampleAutoConfiguration {
public SampleAutoConfiguration(GenericApplicationContext context, RestTemplateProperties properties) {
properties.getRestTemplates().keySet().forEach(name -> {
RestTemplateProperties.RestTemplateProperty property = properties.getRestTemplates().get("name");
var restTemplate = new RestTemplateBuilder()
.rootUri(property.getRootUri())
.build();
context.registerBean(name + "RestTemplate", RestTemplate.class, () -> restTemplate);
});
}
}
これでBean利用する場合は aRestTemplate
やbRestTemplate
という名前でインジェクションできるようになります!!