Spring之動態注冊bean
什么場景下,需要主動向Spring容器注冊bean呢?
如我之前做個的一個支持掃表的基礎平台,使用者只需要添加基礎配置 + Groovy任務,就可以丟到這個平台上面來運行了,而這個基礎平台是一直都在運行的,所以在新來任務時,最直觀需要注冊的就是 DataSource
數據源這個bean了,那么可以怎么玩?
I. 主動注冊Bean支持
借助BeanDefinition
來實現bean的定義,從最終的使用來看,代碼比較少,幾行而已
public <T> T registerBean(String name, Class<T> clazz, Object... args) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
if (args.length > 0) {
for (Object arg : args) {
beanDefinitionBuilder.addConstructorArgValue(arg);
}
}
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(name, beanDefinition);
return applicationContext.getBean(name, clazz);
}
測試如下
import com.github.hui.story.quickstory.server.VisitService;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class BeanHolder {
private final ConfigurableApplicationContext applicationContext;
public BeanHolder(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
initSer();
}
public void initSer() {
InrSer ser = registerBean("test", InrSer.class);
ser.name = "一灰";
ser.uid = 22;
System.out.println(ser);
InrSer ser2 = registerBean("test2", InrSer.class, "一灰灰Blog", 20);
System.out.println(ser2);
}
@ToString
public static class InrSer {
private String name;
private Integer uid;
@Autowired
private VisitService visitService;
public InrSer() {
}
public InrSer(String name, Integer uid) {
this.name = name;
this.uid = uid;
}
}
private <T> T registerBean(String name, Class<T> clazz, Object... args) {
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
if (args.length > 0) {
for (Object arg : args) {
beanDefinitionBuilder.addConstructorArgValue(arg);
}
}
BeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
BeanDefinitionRegistry beanFactory = (BeanDefinitionRegistry) applicationContext.getBeanFactory();
beanFactory.registerBeanDefinition(name, beanDefinition);
return applicationContext.getBean(name, clazz);
}
}
輸出如下
II. 其他
1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛
2. 聲明
盡信書則不如,已上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
- 微博地址: 小灰灰Blog
- QQ: 一灰灰/3302797840
3. 掃描關注
小灰灰Blog&公眾號
知識星球