如何动态往Spring容器注册/移除bean?

几个关键点需要知道

本文不谈原理,直接上实战。

几个关键点:如何拿到Spring上下文来创建bean或移除bean?如何准备构建bean所需的BeanDefinition?

第一问:可注入bean工厂org.springframework.beans.factory.support.DefaultListableBeanFactory得到;

第二问:使用org.springframework.beans.factory.support.BeanDefinitionBuilder来构建BeanDefinition。

实例

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;

import java.beans.Introspector;
import java.lang.reflect.Modifier;

/**
 * Bean 处理器
 */
@Slf4j
@Component
public class SpringBeanClassHandler {

    /**
     * Bean 工厂
     */
    private final DefaultListableBeanFactory beanFactory;

    public SpringBeanClassHandler(DefaultListableBeanFactory beanFactory) {
        this.beanFactory = beanFactory;
    }

    /**
     * 注册一个普通的bean
     *
     * @param beanCls - 待注册的bean class
     */
    public void registerBean(Class<?> beanCls) {
        if (beanCls == null) {
            return;
        }
        if (Modifier.isAbstract(beanCls.getModifiers())
                || Modifier.isPrivate(beanCls.getModifiers())
                || Modifier.isNative(beanCls.getModifiers())
                || Modifier.isInterface(beanCls.getModifiers())) {
            log.warn("can not support register this class to bean for: {} - {}", beanCls.getName(), Modifier.toString(beanCls.getModifiers()));
        }
        // 注册新的Bean
        String beanName = Introspector.decapitalize(beanCls.getSimpleName());
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(beanCls);
        GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
        definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);// 按类型自动注入
        beanFactory.registerBeanDefinition(beanName, definition);
        log.info("dynamic successfully register bean: {}", beanFactory.getBean(beanName));
    }

    /**
     * 移除 Bean
     *
     * @param beanCls - Bean class
     */
    public void removeBean(Class<?> beanCls) {
        if (beanCls == null) {
            return;
        }
        String clsName = Introspector.decapitalize(beanCls.getSimpleName());
        if (beanFactory.containsBean(clsName)) {
            beanFactory.removeBeanDefinition(clsName);
        }
    }

    /**
     * Spring 容器是否 已存在Bean
     *
     * @param beanCls
     * @return - boolean
     */
    public boolean containsBean(Class<?> beanCls) {
        return beanFactory.containsBean(Introspector.decapitalize(beanCls.getSimpleName()));
    }
}

完结。

相关推荐

  1. 如何动态Spring容器注册/bean

    2024-04-09 17:50:05       35 阅读
  2. Spring Boot 3】动态注入Bean

    2024-04-09 17:50:05       47 阅读
  3. spring系列-动态注册bean

    2024-04-09 17:50:05       43 阅读
  4. spring注册bean-AnnotationBeanDefinitionReader】

    2024-04-09 17:50:05       49 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-09 17:50:05       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-09 17:50:05       106 阅读
  3. 在Django里面运行非项目文件

    2024-04-09 17:50:05       87 阅读
  4. Python语言-面向对象

    2024-04-09 17:50:05       96 阅读

热门阅读

  1. pe格式从入门到图形化显示(五)-RVA和FOA

    2024-04-09 17:50:05       36 阅读
  2. 记一个Unity的异常问题

    2024-04-09 17:50:05       37 阅读
  3. UVA10391 Compound Words 复合词 解题报告

    2024-04-09 17:50:05       29 阅读
  4. Python入门:轻松学习,编程不再难

    2024-04-09 17:50:05       36 阅读
  5. 云智前端面试题

    2024-04-09 17:50:05       32 阅读
  6. 服务器硬件基础知识解析

    2024-04-09 17:50:05       31 阅读
  7. Vue.nextTick() 使用场景及实现原理

    2024-04-09 17:50:05       38 阅读
  8. DockerFile定制镜像

    2024-04-09 17:50:05       32 阅读
  9. Vue3 · 小白学习全局 API:常规

    2024-04-09 17:50:05       38 阅读
  10. 面试前必看,仅供参考

    2024-04-09 17:50:05       34 阅读