国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean

這篇具有很好參考價(jià)值的文章主要介紹了[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean。希望對大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

最近在項(xiàng)目中出現(xiàn)了一個(gè)這種情況:我一頓操作猛如虎的寫了好幾個(gè)設(shè)計(jì)模式,然后在設(shè)計(jì)模式中的類中想將數(shù)據(jù)插入數(shù)據(jù)庫,因此調(diào)用Mapper持久層,但是數(shù)據(jù)怎么都寫不進(jìn)去,在我一頓操作猛如虎的查找下,發(fā)現(xiàn)在普通類中用@Autowired注入的Bean是Null,也就是說注入失敗了,瞎搞。

針對以上情況,我做了三種解決方案,經(jīng)測試均可行,解決方案如下:

  1. 在設(shè)計(jì)模式中只操作數(shù)據(jù),最后還是將數(shù)據(jù)返回給Controller層,再由Controller向下調(diào)用寫入數(shù)據(jù)庫
  2. 簡化設(shè)計(jì)模式,然后將其注冊為Service,然后再Service中調(diào)用Mapper層
  3. 通過Bean工具的方式,在普通類中獲取Bean,然后將內(nèi)容寫入數(shù)據(jù)庫。

經(jīng)過測試,三種情況均可行,最終我選擇了"3"。


- 以下代碼均經(jīng)過我的測試,請放心使用 -

情況復(fù)現(xiàn)

抄作業(yè)可以跳轉(zhuǎn)至正文

情況復(fù)現(xiàn)比較簡單,我們只需要一個(gè)Bean即可,Bean代碼如下:

  1. Bean代碼
@Component
public class TestComponent {

    public String say() {
        System.out.println("執(zhí)行成功");
        return "執(zhí)行成功";
    }
  
}

在以上代碼中,我們將TestComponent注冊成為了一個(gè)Bean,為了嚴(yán)禁,我們還需要在Controller中調(diào)用一下這個(gè)類的方法測試一下該類是否真的被注入進(jìn)去了,但是為了文章不要太冗余,這一塊內(nèi)容我省略掉,結(jié)論是:我測試過,是可以在Controller中調(diào)用的。

  1. 通過普通類調(diào)用該Bean

實(shí)現(xiàn)思想:我們寫一個(gè)普通的類,在Controller中new出該類的對象,然后在該普通類中@Autowired的方式注入該類并調(diào)用

驗(yàn)證方式:首先,我們會輸出該Bean的地址,如果注入成功的話,我們會得到一長串字符,其次,如果成功的話頁面與控制臺均有輸出

  1. Controller層

    只寫個(gè)方法了,類信息略

@GetMapping("/com")
public String common() {
    CommonClazz clazz = new CommonClazz();
    return clazz.say();
}
  1. 普通類CommonClazz
public class CommonClazz {

    @Autowired
    private TestComponent component;

    public String say() {
        System.out.println("-----Bean:"+component);
        return component.say();
    }

}

以上代碼中,我們在Controller層new出來了CommonClazz的對象,在CommonClazz中我們Autowired了測試Bean,隨后返回+輸出,一氣呵成,邏輯嚴(yán)謹(jǐn),看似毫無問題,一執(zhí)行滿是BUG,執(zhí)行結(jié)果如下:

頁面:錯(cuò)誤信息,找不到該頁面(其實(shí)是有該路徑,只不過后臺報(bào)錯(cuò)了)

后臺:報(bào)錯(cuò),內(nèi)容如下

[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean,spring boot,后端,java

可以看到,首先我們對Bean的地址輸出是null,說明我們注入失敗,什么都沒拿到,因此用null來執(zhí)行方法會報(bào)錯(cuò)也就可以理解了。

思考一下,如果我這時(shí)候new一個(gè)Service層的實(shí)現(xiàn)類對象,然后調(diào)用Mapper,是否可以將數(shù)據(jù)寫入數(shù)據(jù)庫呢?答案是否定的,因?yàn)閷τ趎ew出來的Service實(shí)現(xiàn)類來說,它也是一個(gè)普通類,而不是Bean,但是Mapper層卻是一個(gè)Bean,這樣又會出現(xiàn)現(xiàn)在的問題。




正文 | 獲取一個(gè)Bean

方式 1 | 通過實(shí)現(xiàn)ApplicationContextAwre方式獲取Bean

!!強(qiáng)烈推薦?。?/b>

這是一種比較推薦的寫法,我們不用再改寫SpringBoot啟動(dòng)類,且獲取Bean的時(shí)候也不用傳入Bean的名稱,只需要傳入一個(gè).class就可以了。


1.1 實(shí)現(xiàn)

SpringContextUtil代碼如下:

@Component
public class SpringContextUtil implements ApplicationContextAware {

    private static ApplicationContext ac;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ac = applicationContext;
    }

    public static <T> T getBean(Class<T> clazz) {
        T bean = ac.getBean(clazz);
        return bean;
    }

}

正如簡介中所說,這種方法不需要修改啟動(dòng)類,我們只需要做這些就可以正常使用了。


1.2 使用

與方式一相比ControllerCommonClass類并沒有發(fā)生太大的變化,但是為了更好的閱讀性,我們還是全都展示出來。

  1. Controller類(依舊省略類信息,只寫方法)
@GetMapping("/com")
public void common() {
    CommonClazz clazz = new CommonClazz();
    clazz.say();
}
  1. CommonClazz
public class CommonClazz {

    public void say() {
        TestComponent bean = SpringContextUtil.getBean(TestComponent.class);
        System.out.println("-----Bean:"+bean);
        bean.say();
    }

}
  1. Bean類省略,可以去前面復(fù)制

瀏覽器訪問Controller層地址,信息正常輸出,內(nèi)容如下

[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean,spring boot,后端,java

可以看到Bean的地址被正確輸出(說明不是null),也輸出了Bean中方法的內(nèi)容,說明Bean被正常注入了。



方式 2

!推薦!

這種實(shí)現(xiàn)可以在任意類中獲取一個(gè)Bean,但是要修改SpringBoot啟動(dòng)類,并且在獲取Bean的時(shí)候要傳入兩個(gè)參數(shù),有點(diǎn)冗余,個(gè)人覺得使用起來不如方式1(當(dāng)然也可以通過改寫getBean()方法的方式只傳入一個(gè)Bean)。


### 2.1 實(shí)現(xiàn)
  1. 首先我們要簡單改造一下SpringBoot啟動(dòng)類,變動(dòng)如下:
@SpringBootApplication
public class JimTestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(JimTestApplication.class, args);
        SpringContextUtil.setAc(run);
    }

}
  1. 其次,我們創(chuàng)建一個(gè)SpringContextUtil工具類,內(nèi)容如下:
public class SpringContextUtil {
  
    private static ApplicationContext ac;

    public static <T>  T getBean(String beanName, Class<T> clazz) {
        T bean = ac.getBean(beanName, clazz);
        return bean;
    }

    public static void setAc(ApplicationContext applicationContext){
        ac = applicationContext;
    }
}

**大功告成!**接下來只需要在普通類中調(diào)用該工具類中的方法,就可以獲得一個(gè)Bean了,接下來我們測試一下、

測試思路:與上面一樣,我們通過Controller new普通類對象,然后在普通類對象中通過這個(gè)工具類獲取一個(gè)Bean,并且輸出Bean的地址以及調(diào)用Bean的方法

為了方便測試,所有的方法都不加返回值了,直接輸出 ,后面也是如此。


2.2 使用

  1. Controller類new CommonClazz()(依舊省略類信息,直接寫方法)
@GetMapping("/com")
public void common() {
    CommonClazz clazz = new CommonClazz();
    clazz.say();
}
  1. CommonClazz類信息如下
public class CommonClazz {

  public void say() {
      // 使用如下
      TestComponent bean = SpringContextUtil.getBean("testComponent",TestComponent.class);
      System.out.println("-----Bean:"+bean);
      bean.say();
  }

}
  1. Bean(TestComponent)沒有做多大的改動(dòng),只是有返回值改成void了,為了節(jié)省篇幅,這里也省略不寫了。

我們在瀏覽器調(diào)用Controller的地址之后,控制臺得到如下輸出:

[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean,spring boot,后端,java

結(jié)論:Bean被正確注入



方式 3 | 繼承ApplicationObjectSupport的方式獲取Bean

!!不推薦!!

這是一種比較雞肋的方法,使用起來有很大的局限性:它只能在Bean中使用。因?yàn)樗旧硪残枰鳛锽ean被注入后才能生效。


3.1 實(shí)現(xiàn)

  1. SpringContextUtil類內(nèi)容如下
@Service
public class SpringContextUtil extends ApplicationObjectSupport {

    public <T> T getBean(Class<T> clazz) {
        T bean = getApplicationContext().getBean(clazz);
        return bean;
    }

}

3.2 測試

老樣子,為了方便閱讀,我決定省略測試內(nèi)容,直接說測試結(jié)果。

  1. 在普通類中使用,失敗,獲取的測試Bean是一個(gè)null
  2. 在Controller中直接將該類作為Bean@Autowired進(jìn)去(因?yàn)?code>@Service注解就想到了),獲取Bean成功
  3. 我也嘗試了一些其他的辦法在普通類中使用,均失敗了,有好辦法的話告訴我吧。



方式 4 | 繼承WebApplicationObjectSupport

??!不推薦!!

與**[方式3]**一樣,它也只能在Bean中使用,因此也很不推薦。


### 4.1 實(shí)現(xiàn)
@Service
public class SpringContextUtil extends WebApplicationObjectSupport {

    public <T> T getBean(Class<T> clazz) {
        T bean = getApplicationContext().getBean(clazz);
        return bean;
    }

}

4.2 測試

同[方式3],略。



方式 5 | 通過WebApplicationContextUtils

??!不推薦!!

適用于web項(xiàng)目的b/s結(jié)構(gòu)。只適合獲取web項(xiàng)目中。

補(bǔ)充:該bean 定義對應(yīng)于單個(gè)websocket 的生命周期。該作用域僅適用于WebApplicationContext環(huán)境。


5.1 實(shí)現(xiàn)

  1. SpringContextUtil代碼
public class SpringContextUtil {

    public static <T> T getBean(ServletContext request, String name, Class<T> clazz){
        WebApplicationContext webApplicationContext = WebApplicationContextUtils.getRequiredWebApplicationContext(request);
        // 或者
        WebApplicationContext webApplicationContext1 = WebApplicationContextUtils.getWebApplicationContext(request);
//        webApplicationContext1.getBean(name, clazz)
        T bean = webApplicationContext.getBean(name, clazz);
        return bean;
    }

}

5.2 測試

  1. 首先第一個(gè)參數(shù)不能傳遞null,否則會報(bào)錯(cuò)
  2. 暫時(shí)沒有這種場景,后面我就沒測(偷懶




致謝

感謝 華為云 | springboot獲取bean的幾種常用方式 對本博客的幫助文章來源地址http://www.zghlxwxcb.cn/news/detail-805875.html

到了這里,關(guān)于[SpringBoot]如何在一個(gè)普通類中獲取一個(gè)Bean的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Boot |如何讓你的 bean 在其他 bean 之前完成加載

    Spring Boot |如何讓你的 bean 在其他 bean 之前完成加載

    問題 今天有個(gè)小伙伴給我出了一個(gè)難題:在 SpringBoot 中如何讓自己的某個(gè)指定的 Bean 在其他 Bean 前完成被 Spring 加載?我聽到這個(gè)問題的第一反應(yīng)是,為什么會有這樣奇怪的需求? Talk is cheap,show me the code,這里列出了那個(gè)想做最先加載的“天選 Bean” 的代碼,我們來分析一

    2024年02月05日
    瀏覽(19)
  • 如何獲取springboot中所有的bean

    這段代碼是一個(gè)使用 Spring Framework 的依賴注入(DI)功能的示例。它用 @Autowired 注解將一個(gè)類型為 MapString, Object 的變量聲明為一個(gè)由 Spring 容器管理的 bean,并初始化為一個(gè)線程安全的 ConcurrentMap 實(shí)現(xiàn)對象。 從代碼中可以看出以下幾點(diǎn): @Autowired :這是 Spring Framework 提供的一

    2024年02月09日
    瀏覽(15)
  • 超越競爭:Spring Boot如何在加載bean時(shí)優(yōu)先選擇我?

    超越競爭:Spring Boot如何在加載bean時(shí)優(yōu)先選擇我?

    ?? 歡迎點(diǎn)贊 ?? 收藏 ?留言 ?? 如有錯(cuò)誤敬請指正! Spring Boot 是當(dāng)前業(yè)界最受歡迎和廣泛使用的 Java Web 應(yīng)用開發(fā)框架之一。在 Spring Boot 應(yīng)用中,bean 是通過自動(dòng)配置進(jìn)行裝載的,因?yàn)槠浒凑占s定順序位置,Spring Boot 希望盡可能提供正確的自動(dòng)配置,在應(yīng)用運(yùn)行時(shí)重寫或自

    2023年04月08日
    瀏覽(26)
  • spring boot mybatis plus mapper如何自動(dòng)注冊到spring bean容器

    spring boot mybatis plus mapper如何自動(dòng)注冊到spring bean容器

    ##@Import(AutoConfiguredMapperScannerRegistrar.class) ##注冊MapperScannerConfigurer ##MapperScannerConfigurer.postProcessBeanDefinitionRegistry方法掃描注冊mapper ##找到mapper候選者 ##過濾mapper 類 候選者 ##BeanDefinitionHolder注冊到spring 容器

    2024年01月17日
    瀏覽(28)
  • spring復(fù)習(xí):(35)在getBean時(shí),在哪里根據(jù)普通bean和工廠bean進(jìn)行區(qū)分處理來返回的?

    spring復(fù)習(xí):(35)在getBean時(shí),在哪里根據(jù)普通bean和工廠bean進(jìn)行區(qū)分處理來返回的?

    在AbstractBeanFactory的doGetBean方法: 調(diào)用的getObjectForBeanInstance方法部分代碼如下: 如果不是工廠bean,則直接將實(shí)例返回,否則調(diào)用getObjectFromFactoryBean方法獲取工廠bean的getObject方法返回的對象 其中調(diào)用了doGetObjectFromFactoryBean方法,代碼如下: 可以看到工廠bean的getObject方法被調(diào)用

    2024年02月16日
    瀏覽(29)
  • 在 Qt 的文本編輯類中,document() 是一個(gè)成員函數(shù),用于獲取文檔對象

    在 Qt 的文本編輯類中, document() 是一個(gè)成員函數(shù),用于獲取文檔對象。它返回與文本編輯器關(guān)聯(lián)的 QTextDocument 對象的指針。 QTextDocument 類是 Qt 中用于處理富文本內(nèi)容的類。它包含了文本內(nèi)容以及相關(guān)的格式、樣式和布局信息。通過 document() 函數(shù),可以獲取到當(dāng)前文本編輯器

    2024年02月04日
    瀏覽(32)
  • 【Spring Boot】Spring Boot項(xiàng)目中如何查看springBoot版本和Spring的版本

    【Spring Boot】Spring Boot項(xiàng)目中如何查看springBoot版本和Spring的版本

    在項(xiàng)目中查看默認(rèn)版本有兩種方式如下 Spring Boot 的最新版本支持情況: 版本 發(fā)布時(shí)間 停止維護(hù)時(shí)間 停止商業(yè)支持 3.0.x 2022-11-24 2023-11-24 2025-02-24 2.7.x 2022-05-19 2023-11-18 2025-02-18 2.6.x 2021-12-17 2022-11-24 2024-02-24 2.5.x 2021-05-20 已停止 2023-08-24 2.4.x 2020-11-12 已停止 2023-02-23 2.3.x 2020-05-

    2024年02月11日
    瀏覽(45)
  • 如何自己實(shí)現(xiàn)一個(gè)Spring Boot Starter

    如何自己實(shí)現(xiàn)一個(gè)Spring Boot Starter

    現(xiàn)在很多開源的組件都會提供對應(yīng)的 springboot-starter 包給我們?nèi)ビ?,要做一個(gè) starter 包并不難。參照Spring內(nèi)置的實(shí)現(xiàn)就好了: 1、在工程里引入 starter 打包相關(guān)的依賴。 2、在我們工程內(nèi)建 spring.factories 文件,編寫我們配置類的全限類名。 使用AOP實(shí)現(xiàn)攔截方法執(zhí)行和打印日志的

    2024年01月22日
    瀏覽(19)
  • SpringBoot-1-Spring Boot實(shí)戰(zhàn):快速搭建你的第一個(gè)應(yīng)用,以及了解原理

    SpringBoot-1-Spring Boot實(shí)戰(zhàn):快速搭建你的第一個(gè)應(yīng)用,以及了解原理

    SpringBootWeb入門 我們在之前介紹Spring的時(shí)候,已經(jīng)說過Spring官方(Spring官方)提供很多開源項(xiàng)目,點(diǎn)擊projects,看到spring家族旗下的項(xiàng)目 Spring發(fā)展到今天已經(jīng)形成了一種開發(fā)生態(tài)圈,Spring提供了若干個(gè)子項(xiàng)目,每個(gè)項(xiàng)目用于完成特定的功能。而我們在項(xiàng)目開發(fā)時(shí),一般會偏向于選

    2024年02月12日
    瀏覽(92)
  • Spring Boot學(xué)習(xí)隨筆-第一個(gè)SpringBoot項(xiàng)目快速啟動(dòng)(org.springframework.boot、@SpringBootApplication、application.yml)

    Spring Boot學(xué)習(xí)隨筆-第一個(gè)SpringBoot項(xiàng)目快速啟動(dòng)(org.springframework.boot、@SpringBootApplication、application.yml)

    學(xué)習(xí)視頻:【編程不良人】2021年SpringBoot最新最全教程 創(chuàng)建第一個(gè)Module 環(huán)境要求 jdk1.8+ maven3.2+ Spring Framework 5.x+ Tomcat 9.0+ IDEA 2021 自動(dòng)保存刷新pom 在resources下添加application.yml文件后,即可啟動(dòng)springboot應(yīng)用 由于tomcat內(nèi)嵌在springboot里面了,所以我們在修改端口號等設(shè)置也在配置

    2024年02月05日
    瀏覽(38)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包