SPRING 动态注册BEAN

2020-12-27 01:28

阅读:545

标签:test   构造参数   exception   实现   getc   random   red   autoconf   anr   

场景

有些情况下,不能直接使用BEAN的方式:

@Bean(name = "storage")
    public DataSourceProxy storageDataSourceProxy(@Qualifier("originStorage") DataSource dataSource) {
        return new DataSourceProxy(dataSource);
    }

比如有些情况下,需要将BEAN 动态加入SPRING 容器中,但是上面的方式是固定的,实现不了在容器中动态注册BEAN。

 

实现方式

增加一个动态注册工具类:

package com.redxun.common.utils;

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;

public class ManualRegistBeanUtil {

    /**
     * 主动向Spring容器中注册bean
     *
     * @param applicationContext Spring容器
     * @param name               BeanName
     * @param clazz              注册的bean的类性
     * @param args               构造方法的必要参数,顺序和类型要求和clazz中定义的一致
     * @param 
     * @return 返回注册到容器中的bean对象
     */
    public static  T registerBean(ConfigurableApplicationContext applicationContext, String name, Class clazz,
                                     Object... args) {
        if(applicationContext.containsBean(name)) {
            Object bean = applicationContext.getBean(name);
            if (bean.getClass().isAssignableFrom(clazz)) {
                return (T) bean;
            } else {
                throw new RuntimeException("BeanName 重复 " + name);
            }
        }
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
        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);
    }

}
applicationContext:spring 容器上下文

name:bean 的名称
clazz:需要注入的类
args : 类的构造参数。

注入无依赖的Bean

 编写代码:

import lombok.extern.slf4j.Slf4j;

import java.util.Random;

@Slf4j
public class ManualBean {

    private int id;
    private String name;

    public ManualBean() {
        Random random = new Random();
        id = random.nextInt(100);
    }

    public ManualBean(String msg) {
         this.name=msg;
    }

    public String print( ) {
        return "[ManualBean] print : " + name + " id: " + id;
    }
}

注入测试:

import com.redxun.common.utils.ManualRegistBeanUtil;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;

@Component
public class BeanRegisterAutoConf {

    public BeanRegisterAutoConf(ApplicationContext applicationContext) {
        System.out.println("BeanRegisterAutoConf init: " + System.currentTimeMillis());
        registerManualBean((ConfigurableApplicationContext) applicationContext);
    }


    private void registerManualBean(ConfigurableApplicationContext applicationContext) {
        // 主动注册一个没什么依赖的Bean
        ManualBean manualBean = ManualRegistBeanUtil.registerBean(applicationContext, "manualBean", ManualBean.class,"RAY");
        manualBean.print();

    }


}

这里使用了构造参数的方式进行注入。

测试注入是否可用

编写测试用例

@Test
    public void testRegseterBean(){
        ManualBean bean= SpringUtil.getBean("manualBean");
        String str= bean.print();
        System.err.println(str);
    }

注入有有依赖

 

 

 

SPRING 动态注册BEAN

标签:test   构造参数   exception   实现   getc   random   red   autoconf   anr   

原文地址:https://www.cnblogs.com/yg_zhang/p/13032797.html


评论


亲,登录后才可以留言!