阅读 26

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. 一灰灰Blog: https://liuyueyi.github.io/hexblog

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

2. 声明

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

3. 扫描关注

小灰灰Blog&公众号

QrCode

知识星球

zhishi

关注下面的标签,发现更多相似文章
评论