1. 概述
Spring beans 通常通過註解(如 @Component 或 @Bean)進行聲明式註冊。但是,在某些情況下,我們可能需要比程序註冊提供更多的靈活性,例如基於屬性註冊 bean。
Spring 7 引入了 BeanRegistrar 作為一項強大的新特性。
在本教程中,我們將探討 BeanRegistrar 為什麼是一個受歡迎的補充,它與舊的註冊 bean 的方式相比如何,以及如何在 Java 和 Kotlin 項目中使用它。
2. 我們為什麼需要新東西
在 Spring 7 之前,我們已經可以通過 BeanDefinitionRegistryPostProcessor 類型程序化地註冊 Bean:
@Configuration
public class BeanRegistrationsSpring6Configuration {
@Bean
BeanDefinitionRegistryPostProcessor beanDefinitionRegistryPostProcessor() {
return new BeanDefinitionRegistryPostProcessor() {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
var beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(MyService.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
registry.registerBeanDefinition("myService", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// No-op
}
};
}
}雖然具有靈活性,但也存在一些缺點:
- 它冗餘且低級。
- 難以閲讀和測試。
- 不適合本機圖像(AOT)場景。
3. 新的 BeanRegistrar 類型
BeanRegistrar 是一個功能接口,它允許我們以一種乾淨、聲明式和原生兼容的方式註冊 Bean。 下面的示例使用 BeanRegistrar 將一個類型為 MyService 的 Bean 註冊,並使用默認設置,以及另一個名為 “myService2” 的 Bean,具有原型作用域和程序化惰性初始化:
@Configuration
@Import(BeanRegistrationsConfiguration.MyBeanRegistrar.class)
public class BeanRegistrationsConfiguration {
static class MyBeanRegistrar implements BeanRegistrar {
@Override
public void register(BeanRegistry registry, Environment env) {
registry.registerBean(MyService.class);
registry.registerBean("myService2", MyService.class, spec -> spec
.prototype()
.lazyInit()
.primary()
);
}
}
}
我們需要意識到不能使用 @Bean 風格來定義 BeanRegistrar。 而是應該使用 @Import,因為 Bean 必須在 Spring 的配置處理期間被發現。
4. Kotlin DSL 支持
對於 Kotlin,我們可以使用 BeanRegistrarDsl 以獲得一流的支持。相同的示例將變為如下所示:
@Configuration
@Import(BeanRegistrationsConfiguration.MyBeanRegistrar::class)
class BeanRegistrationsConfiguration {
class MyBeanRegistrar : BeanRegistrarDsl({
registerBean<MyService>()
registerBean( name = "myService2", prototype = true, lazyInit = true ){
MyService()
}
})
}
5. 結論
在本文中,我們瞭解到 BeanRegistrar 是一個允許我們以簡潔、聲明式和原生兼容的方式註冊 Bean 的特性。
關於該特性的原始討論可以在 Spring Framework 項目的 GitHub 倉庫 中找到。