Spring之动态注册bean

什么场景下,需要主动向Spring容器注册bean呢?

如我之前做个的一个支持扫表的基础平台,使用者只需要添加基础配置 + Groovy任务,就可以丢到这个平台上面来运行了,而这个基础平台是一直都在运行的,所以在新来任务时,最直观需要注册的就是 DataSource 数据源这个bean了,那么可以怎么玩?

I. 主动注册Bean支持

借助BeanDefinition来实现bean的定义,从最终的使用来看,代码比较少,几行而已

1
2
3
4
5
6
7
8
9
10
11
12
13
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);
}

测试如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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);
}
}

输出如下

show

II. 其他

1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

2. 声明

尽信书则不如,已上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

3. 扫描关注

一灰灰blog

QrCode

知识星球

goals