zoukankan      html  css  js  c++  java
  • Spring-IOC BeanFactory运行时动态注册bean

    在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
  • 相关阅读:
    MySQL 替换和截取指定位置字符串
    notepad++安装XML格式化插件
    个人信用报告,长啥样?怎么查?
    MySQL 查询decimal字段去除自动补零
    mapstruct使用详解
    电商物流行业中的RDC、FDC和TDC分别表示什么意思?发网详解
    借助Proxifier实现内网访问
    C++源码流程图分析!
    FFmpeg中AVPacket处理函数av_free_packet()和av_packet_free()的区别以及用法
    fopen 和它的读写标识 r、r+、rb+、rt+、w+.....
  • 原文地址:https://www.cnblogs.com/leihuazhe/p/8137564.html
Copyright © 2011-2022 走看看