方案一:使用?@Primary/
@Qualifier?注解(優選)
如果有多個相同類型的 Bean 存在,可以將想要優先使用的 Bean 加上?@Primary
?注解。
@Qualifier和@Primary注解的區別:@Primary注解用于標記具有相同類型的多個實例中的主要實例。而@Qualifier注解用于標記具有特定名稱的Bean,以便在多個具有相同類型的Bean中選擇特定的實例。
例如:接口ContextUserParser有AbsContextUserTokenParser和ContextUserTokenParser兩個實現類,現在我想使用AbsContextUserTokenParser。為此配置config類:
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@Primarypublic ContextUserParser absContextUserTokenParser(YoafUserContextProperties properties){return new AbsContextUserTokenParser(properties);}
}
方式二:自定義 Bean 替換邏輯
通過實現BeanDefinitionRegistryPostProcessor?接口,在其方法中根據特定條件來動態替換 Bean 的定義。
以下是一個簡單示例:
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 {@Overridepublic 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);}}@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {log.debug("beanFactory:{}", beanFactory);}
}
方式三:利用 Spring 的擴展機制
比如通過自定義?ApplicationContextInitializer
?等在特定階段進行 Bean 的替換操作。