1. 程式人生 > >180804-Spring之動態註冊bean

180804-Spring之動態註冊bean

factor mage 定義 uil int ... ans -h actor

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

輸出如下

技術分享圖片

II. 其他

1. 一灰灰Blog: https://liuyueyi.github.io/hexblog

一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

2. 聲明

盡信書則不如,已上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激

  • 微博地址: 小灰灰Blog
  • QQ: 一灰灰/3302797840

3. 掃描關註

小灰灰Blog&公眾號

技術分享圖片

知識星球

技術分享圖片

180804-Spring之動態註冊bean