zoukankan      html  css  js  c++  java
  • 180804-Spring之动态注册bean

    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);
        }
    }
    

    输出如下

    show

    II. 其他

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

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

    2. 声明

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

    3. 扫描关注

    小灰灰Blog&公众号

    QrCode

    知识星球

    zhishi

  • 相关阅读:
    关于加法的类型转换
    设备事件
    html5 事件
    【环境安装】快速安转TensorFlow
    JApiDocs API文档-超级好用
    Docker(超级详细)
    SpringBoot整合Swagger
    Jenkins +Docker+Git 实现自动部署
    Git commit规范
    java支付宝生成二维码
  • 原文地址:https://www.cnblogs.com/yihuihui/p/9420301.html
Copyright © 2011-2022 走看看