Skip to content
章节导航

通过 BeanDefinition 自定义 Bean

创建一个类

java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.ExecutorService;

/**
 * MessageHandler
 *
 * @author 朔风
 * @date 2026-01-13 14:30
 */
public class MessageHandler {
    private static final Logger logger = LoggerFactory.getLogger(MessageHandler.class);

    private final String handlerName;
    private final IUserInfoService userInfoService;
    private final ExecutorService executorService;

    public MessageHandler(String handlerName,
                          IUserInfoService userInfoService,
                          ExecutorService executorService) {

        this.handlerName = handlerName;
        this.userInfoService = userInfoService;
        this.executorService = executorService;
    }

    /***
     * bean 初始化的执行方法
     *
     * @author 朔风
     * @date 2026/1/13 14:37
     * @return void
     */
    public void start() {
        logger.info("MessageHandler start .....");
    }

    /***
     * bean 销毁的执行方法
     *
     * @author 朔风
     * @date 2026/1/13 14:37
     * @return void
     */
    public void close() {
        logger.info("MessageHandler close .....");
    }

}

自定义 Bean 注册

java
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * 自定义 Bean 注册
 *
 * @author 朔风
 * @date 2026-01-13 14:36
 */
@Component
public class CustomBeanRegistry implements BeanDefinitionRegistryPostProcessor {
    private static final Logger logger = LoggerFactory.getLogger(CustomBeanRegistry.class);

    public static final String PROCESSOR_BEAN_NAME = "userInfoServiceImpl";
    public static final String BEAN_NAME_PREFIX = "multiMessageHandler";

    /**
     * bean 初始化与销毁的执行方法
     */
    public static final String INIT_METHOD_NAME = "start";
    public static final String DESTROY_METHOD_NAME = "close";

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
            throws BeansException {

        String beanName = buildBeanName("messageHandler");
        BeanDefinition definition = buildBeanDefinition("messageHandler");
        registry.registerBeanDefinition(beanName, definition);
        logger.info("CustomBeanRegistry postProcessBeanDefinitionRegistry ......");
    }

    /***
     * 生成一个新的 Bean 元数据定义
     *
     * @author 朔风
     * @date 2026/1/13 14:38
     * @return org.springframework.beans.factory.support.GenericBeanDefinition
     */
    public GenericBeanDefinition newBeanDefinition() {
    
        /* GenericBeanDefinition: 通用的 BeanDefinition  */
        GenericBeanDefinition definition = new GenericBeanDefinition();
        definition.setScope(GenericBeanDefinition.SCOPE_SINGLETON);  // 作用域:单例
        definition.setAbstract(false); // 是否抽象,如果是抽象的,将不会被 IOC 实例化
        definition.setLazyInit(false); // 是否需要延迟实例化:false-默认值,容器启动的时候,就会被实例化,
        definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_NO); // 自动装配模式, 这类选择不使用自动装配,因为我们会通过自定义构造函数【MessageHandler】完成装配
        definition.setDependencyCheck(GenericBeanDefinition.DEPENDENCY_CHECK_NONE); // 设置依赖检查,这里设置不做检查,因为 MessageHandler 我们是手动装配的
        definition.setDependsOn(); // 依赖的 bean 名称,这类没有依赖任何 bean
        definition.setAutowireCandidate(false); // 是否链接为其他 bean 的候选 bean,很少会用到的一个属性,默认值为 false
        definition.setPrimary(false); // 是否为主要的首选(Primary)Bean 机制,多个同类型的 bean 时才会用到,设置为 true 它为首选,例如多数据源
        definition.setNonPublicAccessAllowed(true); // 是否允许 Spring 访问和实例化非公有(non-public)的构造方法
        definition.setLenientConstructorResolution(false); // 是否在宽松模式下解析构造函数,很少用到,默认为 false
        definition.setInitMethodName(INIT_METHOD_NAME); // bean 初始化时启动的方法
        definition.setDestroyMethodName(DESTROY_METHOD_NAME); // bean 注销时启动的方法
        definition.setSynthetic(true); // 是否是合成的
        definition.setRole(GenericBeanDefinition.ROLE_APPLICATION); // 角色:应用程序级别

        return definition;
    }

    private String buildBeanName(String handlerName) {
        return String.format("%s_%s", BEAN_NAME_PREFIX, handlerName);
    }

    private ExecutorService buildExecutor() {
        return new ThreadPoolExecutor(1, 1, 60,
                TimeUnit.MINUTES, new SynchronousQueue<>());
    }

    /***
     * 构建我们想要注册到 IOC 中的 bean
     *
     * @author 朔风
     * @date 2026/1/13 14:36
     * @param handlerName handlerName
     * @return org.springframework.beans.factory.config.BeanDefinition
     */
    private BeanDefinition buildBeanDefinition(String handlerName) {

        /* 构造函数信息 */
        ConstructorArgumentValues values = new ConstructorArgumentValues();
        values.addIndexedArgumentValue(0, buildBeanName(handlerName));  // 构造函数第一个参数
        values.addIndexedArgumentValue(1, new RuntimeBeanReference(PROCESSOR_BEAN_NAME)); // 构造函数第二个参数
        values.addIndexedArgumentValue(2, buildExecutor()); // 构造函数第三个参数

        GenericBeanDefinition definition = newBeanDefinition();
        // 描述信息
        definition.setDescription(buildBeanName(handlerName));
        // 构造参数, 依赖
        definition.setConstructorArgumentValues(values);
        // bean 信息
        definition.setBeanClassName(MessageHandler.class.getName());
        definition.setBeanClass(MessageHandler.class);

        GenericBeanDefinition definition = newBeanDefinition();
        // 描述信息
        definition.setDescription(buildBeanName(handlerName));
        // 构造参数, 依赖
        definition.setConstructorArgumentValues(values);
        // bean 信息
        definition.setBeanClassName(MessageHandler.class.getName());
        definition.setBeanClass(MessageHandler.class);

        return definition;
    }

}