亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

springboot項目中出現同名bean異常報錯的解決方法

 更新時間:2024年01月09日 10:35:02   作者:linyb極客之路  
這篇文章給大家聊聊springboot項目出現同名bean異常報錯如何修復,文中通過代碼示例給大家介紹解決方法非常詳細,對大家的學習或工作有一定的幫助,需要的朋友可以參考下

前言

最近業(yè)務部門接手供方的項目過來二開,其中有個認證實現因為業(yè)務需要,需要替換原有供方實現的邏輯。大概偽代碼如下。供方提供的接口以及默認實現形如下

public interface AuthCodeService {
    default Boolean check() {
        return true;
    }

}

@Service("authCodeService")
public class AuthCodeImpl implements AuthCodeService {

    public Boolean check() {
	    // doBiz
        return true;
    }
}

業(yè)務的替換實現如下

@Service
public class BizAuthCodeImpl implements AuthCodeService {

    public Boolean check() {
	    // doOtherBiz
        return true;
    }
}

然而項目運行的時候,發(fā)現走的認證邏輯始終是供方的邏輯,而非業(yè)務重寫后的邏輯。

平時因為跟業(yè)務的技術負責人走得比較近,他就私下找我交流一下思路。一開始我給他提的建議是說在你定制的業(yè)務類上加@Primary試下,他說他加了但沒效果。

于是我就跟他說不然你直接改供方源碼的默認實現,他給的答復供方沒提供源碼,只提供jar。我就跟他說,這也可以改,你項目創(chuàng)建一個和供方實現一模一樣的類,就是包名和類名一模一樣,利用類的加載順序實現。技術負責人又覺得這樣不好。

后面那個技術負責人想了一個方式,就是他將業(yè)務定制bean名稱和供方提供的bean名稱一樣,形如下

@Service("authCodeService")
public class BizAuthCodeImpl implements AuthCodeService {

    public Boolean check() {
	    // doOtherBiz
        return true;
    }
}

然后項目啟動,直接報了如下錯

org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'authCodeService' for bean class 

他就跟我說這個異常怎么修復,鋪墊了這么久,引來了今天要聊的話題,同名bean異常報錯如何修復

解決思路

首先拋出一個觀點,在同個spring容器中,是不能出現同名的bean,因此解決的思路要么搞成不同的spring容器,要么就是排除多個同名的bean,只保留自己想要的那個。要么就是將bean改個名字。今天介紹的思路就是排除同名bean,只保留自己想要的bean

實現方法

1、方法一:通過@ComponentScan進行排除

示例配置

在springboot的啟動類上加上形如下內容

@ComponentScan(basePackages = {"com.github.lybgeek"},excludeFilters = {@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = AuthCodeImpl.class)})

這邊有個注意點是當你啟動類上同時存在@SpringBootApplication和@ComponentScan注解時,@ComponentScan注解指定的掃描包路徑會覆蓋@SpringBootApplication的包路徑。

我將第一種方案告訴業(yè)務技術負責人后,他試了一下,果然沒報錯,但是后面出現一個問題,他說@SpringBootApplication的屬性exclude()失效了,導致他項目要排除的自動裝配類失效了。于是就有了第二種方案

2、方法二:自定義TypeExcludeFilter

我們點開@SpringBootApplication,可以看到如下內容

@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

既然@SpringBootApplication和@ComponentScan同時標注在啟動類上會有一定沖突,我們就遵循@SpringBootApplication提供的擴展方案就好了,自己寫一個TypeExcludeFilter進行排除

實現步驟

1、自定義TypeExcludeFilter

public class CustomTypeExcludeFilter extends TypeExcludeFilter {

    @Override
    public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
         String className = metadataReader.getClassMetadata().getClassName();
         return AuthCodeImpl.class.getName().equals(className);

    }
}

2、將自定義TypeExcludeFilter注入到spring容器 中

這邊有個特別需要注意的細節(jié)點,因為TypeExcludeFilter是要排除bean的,因此他注入的時機至少要在其他bean注入之前,具體來說就是在容器上下文refresh執(zhí)行之前,就得完成注入。在refresh之前執(zhí)行的擴展點有很多,我們就挑一個,我們以實現ApplicationContextInitializer為例

public class CustomTypeExcludeFilterApplicationContextInitializer implements ApplicationContextInitializer {
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getBeanFactory();
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(CustomTypeExcludeFilter.class);
        AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();

        defaultListableBeanFactory.registerBeanDefinition("customTypeExcludeFilter",beanDefinition);
    }
}

3、將ApplicationContextInitializer 的實現類放在/META-INF/spring.factories

org.springframework.context.ApplicationContextInitializer=\
com.github.lybgeek.context.CustomTypeExcludeFilterApplicationContextInitializer

按照上面三步執(zhí)行,就可以排除自己想排除的bean

總結

當項目中出現同名bean沖突時,如果可以的話,就盡量換個其他bean名稱來解決

后面業(yè)務負責人并沒有采用我上述的方案,我們回歸業(yè)務負責人他們項目訴求,他們的需求是要他們自定義認證的邏輯能生效,而非解決同名bean沖突。

業(yè)務負責人他們最后的方案是通過加@Primary注解解決,他之前加了覺得沒生效,是因為他們項目引的自定義認證邏輯的舊包,那個舊包沒加@Primary注解,后面把包升級就解決了

以上就是springboot項目中出現同名bean異常報錯的解決方法的詳細內容,更多關于springboot出現同名bean的資料請關注腳本之家其它相關文章!

相關文章

  • Netty簡單的入門代碼示例

    Netty簡單的入門代碼示例

    這篇文章主要介紹了Netty簡單的入門代碼示例,Netty 的內部實現是很復雜的,但是 Netty 提供了簡單易用的API從網絡處理代碼中解耦業(yè)務邏輯,Netty 是完全基于 NIO 實現的,所以整個 Netty 都是異步的,需要的朋友可以參考下
    2023-12-12
  • 一文徹底搞定Java哈希表和哈希沖突

    一文徹底搞定Java哈希表和哈希沖突

    本文介紹了什么是哈希表?什么是哈希函數?什么是哈希沖突?三個問題的解決方案,文中有非常詳細的代碼示例,對正在學習java的小伙伴們很有幫助,需要的朋友可以參考下
    2021-05-05
  • spring啟動加載程序的幾種方法介紹

    spring啟動加載程序的幾種方法介紹

    本篇文章主要介紹了spring啟動加載程序的幾種方法介紹,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-04-04
  • Java 并發(fā)編程學習筆記之核心理論基礎

    Java 并發(fā)編程學習筆記之核心理論基礎

    編寫優(yōu)質的并發(fā)代碼是一件難度極高的事情。Java語言從第一版本開始內置了對多線程的支持,這一點在當年是非常了不起的,但是當我們對并發(fā)編程有了更深刻的認識和更多的實踐后,實現并發(fā)編程就有了更多的方案和更好的選擇。本文是對并發(fā)編程的核心理論做了下小結
    2016-05-05
  • Mybatis批量提交實現步驟詳解

    Mybatis批量提交實現步驟詳解

    這篇文章主要介紹了Mybatis批量提交實現步驟詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • Java Swing JComboBox下拉列表框的示例代碼

    Java Swing JComboBox下拉列表框的示例代碼

    這篇文章主要介紹了Java Swing JComboBox下拉列表框的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-12-12
  • Spring?Data?JPA實現持久化存儲數據到數據庫的示例代碼

    Spring?Data?JPA實現持久化存儲數據到數據庫的示例代碼

    Spring Data JPA是Spring基于JPA規(guī)范的基礎上封裝的?套 JPA 應?框架,可使開發(fā)者?極簡的代碼即可實現對數據庫的訪問和操作。本文我們來了解如何用Spring?Data?JPA框架實現數據持久化存儲到數據庫,感興趣的可以了解一下
    2022-04-04
  • 詳解spring多線程與定時任務

    詳解spring多線程與定時任務

    本篇文章主要介紹了spring多線程與定時任務,詳細的介紹了spring多線程任務和spring定時任務,有興趣的可以了解一下。
    2017-04-04
  • spring-data-redis 動態(tài)切換數據源的方法

    spring-data-redis 動態(tài)切換數據源的方法

    最近遇到了一個麻煩的需求,我們需要一個微服務應用同時訪問兩個不同的 Redis 集群,一般情況下我們會怎么處理呢,下面通過場景分析給大家介紹spring-data-redis 動態(tài)切換數據源的方法,感興趣的朋友一起看看吧
    2021-08-08
  • springboot項目部署到k8s上的方法步驟

    springboot項目部署到k8s上的方法步驟

    本文主要介紹了springboot項目部署到k8s上的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-05-05

最新評論