spring 优雅替换bean

方案一:使用 @Primary/@Qualifier 注解(优选)

如果有多个相同类型的 Bean 存在,可以将想要优先使用的 Bean 加上 @Primary 注解。

@Qualifier和@Primary注解的区别:@Primary注解用于标记具有相同类型的多个实例中的主要实例。而@Qualifier注解用于标记具有特定名称的Bean,以便在多个具有相同类型的Bean中选择特定的实例。

例如:接口ContextUserParser有AbsContextUserTokenParser和ContextUserTokenParser两个实现类,现在我想使用AbsContextUserTokenParser。为此配置config类:

java 复制代码
package com.psbc.abs.config;

import com.psbc.pfpj.yoaf.context.autoconfigure.YoafUserContextProperties;
import com.psbc.pfpj.yoaf.context.parser.AbsContextUserTokenParser;
import com.psbc.pfpj.yoaf.context.parser.ContextUserParser;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;

@Configuration
@Slf4j
public class AbsContextUserTokenConfig {
    @Bean
    @Primary
    public ContextUserParser absContextUserTokenParser(YoafUserContextProperties properties){
        return new AbsContextUserTokenParser(properties);
    }
}

方式二:自定义 Bean 替换逻辑

通过实现BeanDefinitionRegistryPostProcessor 接口,在其方法中根据特定条件来动态替换 Bean 的定义。

以下是一个简单示例:

java 复制代码
package com.psbc.abs.support;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;

/**
 * 替换jar包内默认bean
 *
 * @author lijunyu
 * @date 2023/10/23 17:55
 */
@Slf4j
public class OverrideExistsBeanProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        replaceClass(registry,"contextUserParser", AbsContextUserTokenParser.class);
    }

    /**
     * 对容器内现有类进行替换
     *
     * @param beanName 替换类名
     * @param clazz    替换类
     */
    public void replaceClass(BeanDefinitionRegistry registry,String beanName, Class clazz) {
        if (registry.containsBeanDefinition(beanName)) {
            log.debug("bean:{} 删除", beanName);
            registry.removeBeanDefinition(beanName);
            GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
            beanDefinition.setBeanClass(clazz);
            registry.registerBeanDefinition(beanName, beanDefinition);
            log.debug("bean:{} 替换成功", beanName);
        }
    }


    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        log.debug("beanFactory:{}", beanFactory);
        
    }
}

方式三:利用 Spring 的扩展机制

比如通过自定义 ApplicationContextInitializer 等在特定阶段进行 Bean 的替换操作。

相关推荐
CodeAmaz1 分钟前
JVM一次完整GC流程详解
java·jvm·gc流程
想用offer打牌4 分钟前
数据库大事务有什么危害(面试版)
数据库·后端·架构
踏浪无痕13 分钟前
别再只会用 Feign!手写一个 Mini RPC 框架搞懂 Spring Cloud 底层原理
后端·面试·架构
降临-max15 分钟前
JavaWeb企业级开发---Ajax、
java·ajax·maven
NMBG2215 分钟前
外卖综合项目
java·前端·spring boot
小徐Chao努力20 分钟前
Spring AI Alibaba A2A 使用指南
java·人工智能·spring boot·spring·spring cloud·agent·a2a
用户6956194403728 分钟前
前后端分离VUE3+Springboot项目集成PageOffice核心代码
后端
rannn_11129 分钟前
【Git教程】概述、常用命令、Git-IDEA集成
java·git·后端·intellij-idea
我家领养了个白胖胖29 分钟前
向量化和向量数据库redisstack使用
java·后端·ai编程
嘻哈baby33 分钟前
NextCloud私有云盘完整部署指南
后端