spring 程序执行时动态注册 bean 到 context
定义一个没有被 Spring 管理的 Controller
-
public class UserController implements InitializingBean{
-
-
private UserService userService;
-
-
public UserService getUserService() {
-
return userService;
-
}
-
-
public void setUserService(UserService userService) {
-
this.userService = userService;
-
}
-
-
-
public void afterPropertiesSet() throws Exception {
-
System.out.println("我是动态注册的你,不是容器启动的时候注册的你");
-
}
-
-
public String toAction(String content){
-
return "-->" + userService.doService(content);
-
}
-
-
}
需要注意的是,如果要注入 UserService, 需要提供它的 getter 和 setter 方法
现在启动 springboot 工程,显而易见这个类是不会被 Spring 管理的,接下来我们定义一个获取 Spring 上下文的工具类,如下
工具类
-
public class SpringContextUtil {
-
private static ApplicationContext applicationContext;
-
//获取上下文
-
public static ApplicationContext getApplicationContext() {
-
return applicationContext;
-
}
-
//设置上下文
-
public static void setApplicationContext(ApplicationContext applicationContext) {
-
SpringContextUtil.applicationContext = applicationContext;
-
}
-
//通过名字获取上下文中的bean
-
public static Object getBean(String name){
-
return applicationContext.getBean(name);
-
}
-
//通过类型获取上下文中的bean
-
public static Object getBean(Class<?> requiredType){
-
return applicationContext.getBean(requiredType);
-
}
-
}
我们在 Springboot 的启动类中,保存当前 Spring 上下文,代码如下:
-
-
public class HelloApplication {
-
-
public static void main(String[] args) {
-
ApplicationContext app = SpringApplication.run(HelloApplication.class, args);
-
SpringContextUtil.setApplicationContext(app);
-
}
-
-
}
然后我们在另一个被 Spring 管理的容器中,写如下方法,进行 bean 的动态注册
-
@GetMapping("/bean")
-
public String registerBean() {
-
//将applicationContext转换为ConfigurableApplicationContext
-
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();
-
-
// 获取bean工厂并转换为DefaultListableBeanFactory
-
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
-
-
// 通过BeanDefinitionBuilder创建bean定义
-
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserController.class);
-
-
// 设置属性userService,此属性引用已经定义的bean:userService,这里userService已经被spring容器管理了.
-
beanDefinitionBuilder.addPropertyReference("userService", "userService");
-
-
// 注册bean
-
defaultListableBeanFactory.registerBeanDefinition("userController", beanDefinitionBuilder.getRawBeanDefinition());
-
-
-
UserController userController = (UserController) SpringContextUtil.getBean("userController");
-
-
return userController.toAction("动态注册生成调用");
-
-
//删除bean.
-
//defaultListableBeanFactory.removeBeanDefinition("testService");
-
-
}
如上,就能动态的注册 bean。
注意:
假如动态 bean 中属性不是引用 context 中的,需要通过参数传入。
例如:
-
public class UserService{
-
-
private InterfaceGroup group;
-
-
public InterfaceGroup getGroup() {
-
return group;
-
}
-
-
public void setGroup(InterfaceGroup group) {
-
this.group = group;
-
}
-
-
}
-
InterfaceGroup group =new InterfaceGroup();
-
//设置属性....
-
group.setXXX()
-
//传入参数给动态bean引用
-
registerBean(group)
-
/**
-
* 动态注册bean
-
*
-
* @param group 自定义类型
-
* @return
-
*/
-
public void registerBean(InterfaceGroup group) {
-
//将applicationContext转换为ConfigurableApplicationContext
-
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();
-
-
// 获取bean工厂并转换为DefaultListableBeanFactory
-
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
-
-
// 通过BeanDefinitionBuilder创建bean定义
-
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserService.class);
-
-
// 设置属性
-
beanDefinitionBuilder.addPropertyValue("group", group);
-
-
// 注册bean
-
defaultListableBeanFactory.registerBeanDefinition("userService", beanDefinitionBuilder.getRawBeanDefinition());
-
//通过工具类获取动态注册的bean
-
LOG.info((SpringContextUtil.getBean("userService")).toString());
在 spring 运行时,动态的添加 bean,dapeng 框架在解析 xml 的 soa:service 字段时,使用到了动态注册,注册了一个实现了
FactoryBean
类!
定义一个没有被 Spring 管理的 Controller
public class UserController implements InitializingBean{
private UserService userService;
public UserService getUserService() {
return userService;
}
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("我是动态注册的你,不是容器启动的时候注册的你");
}
public String toAction(String content){
return "-->" + userService.doService(content);
}
}
需要注意的是,如果要注入 UserService, 需要提供它的 getter 和 setter 方法
现在启动 springboot 工程,显而易见这个类是不会被 Spring 管理的,接下来我们定义一个获取 Spring 上下文的工具类,如下
工具类
public class SpringContextUtil {
private static ApplicationContext applicationContext;
//获取上下文
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//设置上下文
public static void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
//通过名字获取上下文中的bean
public static Object getBean(String name){
return applicationContext.getBean(name);
}
//通过类型获取上下文中的bean
public static Object getBean(Class<?> requiredType){
return applicationContext.getBean(requiredType);
}
}
我们在 Springboot 的启动类中,保存当前 Spring 上下文,代码如下:
@SpringBootApplication
public class HelloApplication {
public static void main(String[] args) {
ApplicationContext app = SpringApplication.run(HelloApplication.class, args);
SpringContextUtil.setApplicationContext(app);
}
}
然后我们在另一个被 Spring 管理的容器中,写如下方法,进行 bean 的动态注册
@GetMapping("/bean")
public String registerBean() {
//将applicationContext转换为ConfigurableApplicationContext
ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();
// 获取bean工厂并转换为DefaultListableBeanFactory
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();
// 通过BeanDefinitionBuilder创建bean定义
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(UserController.class);
// 设置属性userService,此属性引用已经定义的bean:userService,这里userService已经被spring容器管理了.
beanDefinitionBuilder.addPropertyReference("userService", "userService");
// 注册bean
defaultListableBeanFactory.registerBeanDefinition("userController", beanDefinitionBuilder.getRawBeanDefinition());
UserController userController = (UserController) SpringContextUtil.getBean("userController");
return userController.toAction("动态注册生成调用");
//删除bean.
//defaultListableBeanFactory.removeBeanDefinition("testService");
}
如上,就能动态的注册 bean
摘抄自网络,便于检索查找。