1 场景
spring运行过程中
,有时候需要在程序中动态添加bean
。本文主要记录动态添加bean的方式。
2 代码
2.1 准备
(1) Spring命名空间工具类
定义如下工具类,可以在非spring命名空间内
用来获取spring命名空间:
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* 获取spring命名空间
* @return
*/
public static ApplicationContext getSpringContext(){
return SpringContextUtil.applicationContext;
}
}
如在spring命名空间内
,通过如下方式注入ApplicationContext
即可:
@Autowired
private ApplicationContext applicationContext;
(2)相关测试依赖类**
@Service
public class UserService{
public void method(){
System.out.println("UserService method");
}
}
@Service
public class OtherService {
public void method(){
System.out.println("OtherService method");
}
}
@Data
public class UserConfig {
/**
* 基本属性
*/
private String userCode;
private Integer age;
/**
* 自动注入bean
*/
@Autowired
private UserService userService;
/**
* 手动注册bean(可通过“构造函数”或“手动set注入”)
*/
private OtherService otherService;
/**
* 构造函数
*
* @param userCode
* @param otherService
*/
public UserConfig(String userCode, OtherService otherService) {
this.userCode = userCode;
this.otherService = otherService;
}
/**
* 方法
*/
public void out() {
this.userService.out();
this.otherService.out();
}
}
2.2 注册bean
// ------ 1、创建bean定义
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserConfig.class);
// ------ 2、初始化属性
//(1)【构造参数】设置(如果有)
// 简单属性
beanDefinitionBuilder.addConstructorArgValue("张三");
// 注入属性
beanDefinitionBuilder.addConstructorArgReference("otherService");
// (2)【基本属性】设置(如果有)
// 简单属性
beanDefinitionBuilder.addPropertyValue("age", 19);
// 注入属性
// beanDefinitionBuilder.addAutowiredProperty("otherService");
// ------ 3、注册bean
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getSpringContext();
BeanDefinitionRegistry beanDefinitionRegistry = (BeanDefinitionRegistry) configurableApplicationContext.getBeanFactory();
beanDefinitionRegistry.registerBeanDefinition("userConfig", beanDefinitionBuilder.getRawBeanDefinition());
2.3 测试
// bean存在标志(true:已存在;false:不存在)
boolean containsNameFlag = SpringContextUtil.getSpringContext().containsBean("userConfig");
System.out.println("创建结果:" + (containsNameFlag ? "成功" : "失败"));
UserConfig userConfigs = SpringContextUtil.getSpringContext().getBean(UserConfig.class);
System.out.println(userConfigs);
userConfigs.out();
输出结果:
创建结果:成功
UserConfig(userCode=张三, age=19, userService=com.sa.example.context.service.UserService@3fdecce, otherService=com.sa.example.context.service.OtherService@344426bf)
UserService out
OtherService out
3 备注
spring手动创建bean之前,一般会先判断此bean是否已存在
,同时,创建bean后,也可判断命名空间中是否创建成功
。可通过如下代码判断:
// bean存在标志(true:已存在;false:不存在)
boolean containsNameFlag = SpringContextUtil.getSpringContext().containsBean("xxxBeanName");