欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring通過(guò)工具類實(shí)現(xiàn)獲取容器中的Bean

 更新時(shí)間:2022年06月23日 15:18:44   作者:江南一點(diǎn)雨  
在實(shí)際開發(fā)中,我們往往要用到Spring容器為我們提供的諸多資源,例如想要獲取到容器中的配置、獲取到容器中的Bean等等。本文為大家詳細(xì)講講工具類如何獲取到Spring容器中的Bean,需要的可以參考一下

1. Aware 接口

小伙伴們知道,Spring 容器最大的特點(diǎn)在于所有的 Bean 對(duì)于 Spring 容器的存在是沒(méi)有意識(shí)的,因此我們常說(shuō)理論上你可以無(wú)縫將 Spring 容器切換為其他容器(然而在現(xiàn)實(shí)世界中,我們其實(shí)沒(méi)有這樣的選擇,除了 Spring 容器,難道還有更好用的?)。

當(dāng)然這只是一個(gè)理論,在實(shí)際開發(fā)中,我們往往要用到 Spring 容器為我們提供的諸多資源,例如想要獲取到容器中的配置、獲取到容器中的 Bean 等等。在這種情況下,就需要 Spring 容器中的 Bean 真正的意識(shí)到 Spring 容器的存在,才能要到這些東西,那么如何讓一個(gè) Bean 意識(shí)到 Spring 容器的存在呢?

這就依賴于 Spring 容器給我們提供的各種 Aware 接口了。

/**
?*?A?marker?superinterface?indicating?that?a?bean?is?eligible?to?be?notified?by?the
?*?Spring?container?of?a?particular?framework?object?through?a?callback-style?method.
?*?The?actual?method?signature?is?determined?by?individual?subinterfaces?but?should
?*?typically?consist?of?just?one?void-returning?method?that?accepts?a?single?argument.
?*
?*?<p>Note?that?merely?implementing?{@link?Aware}?provides?no?default?functionality.
?*?Rather,?processing?must?be?done?explicitly,?for?example?in?a
?*?{@link?org.springframework.beans.factory.config.BeanPostProcessor}.
?*?Refer?to?{@link?org.springframework.context.support.ApplicationContextAwareProcessor}
?*?for?an?example?of?processing?specific?{@code?*Aware}?interface?callbacks.
?*
?*?@author?Chris?Beams
?*?@author?Juergen?Hoeller
?*?@since?3.1
?*/
public?interface?Aware?{

}

從這個(gè)接口的注釋中,我們也能大概看出來(lái),這個(gè)接口的子類,主要是提供了一些只有一個(gè)參數(shù)的 set 方法,通過(guò)這些方法可以讓 Spring 容器感知到某一件事情。

Aware 的實(shí)現(xiàn)有很多,大的方向來(lái)說(shuō)主要有如下一些:

每一個(gè) Aware 的作用如下:

  • ApplicationEventPublisherAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取事件發(fā)布的能力。
  • ServletContextAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到 ServletContext 對(duì)象。
  • MessageSourceAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到 MessageSource 對(duì)象,MessageSource 支持多消息源,主要用于主要用于國(guó)際化。
  • ResourceLoaderAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) ResourceLoader,Spring ResourceLoader 則為我們提供了一個(gè)統(tǒng)一的 getResource() 方法來(lái)通過(guò)資源路徑檢索外部資源,例如文本文件、XML 文件、屬性文件或圖像文件等。
  • ApplicationStartupAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) ApplicationStartup 對(duì)象,這個(gè)比較新,是 Spring 5.3 中新推出的,通過(guò) ApplicationStartup 可以標(biāo)記應(yīng)用程序啟動(dòng)期間的步驟,并收集有關(guān)執(zhí)行上下文或其處理時(shí)間的數(shù)據(jù)。
  • NotificationPublisherAware:實(shí)現(xiàn)該接的對(duì)象可以獲取到一個(gè) NotificationPublisher 對(duì)象,通過(guò)該對(duì)象可以實(shí)現(xiàn)通知的發(fā)送。
  • EnvironmentAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) Environment 對(duì)象,通過(guò) Environment 可以獲取到容器的環(huán)境信息。
  • BeanFactoryAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) BeanFactory 對(duì)象,通過(guò) BeanFactory 可以完成 Bean 的查詢等操作。
  • ImportAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) AnnotationMetadata 對(duì)象,ImportAware 接口是需要和 @Import 注解一起使用的。在 @Import 作為元注解使用時(shí),通過(guò) @Import 導(dǎo)入的配置類如果實(shí)現(xiàn)了 ImportAware 接口就可以獲取到導(dǎo)入該配置類接口的數(shù)據(jù)配置。
  • EmbeddedValueResolverAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) StringValueResolver 對(duì)象,通過(guò) StringValueResolver 對(duì)象,可以讀取到 Spring 容器中的 properties 配置的值(YAML 配置也可以)。
  • ServletConfigAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) ServletConfig 對(duì)象,不過(guò)這個(gè)似乎沒(méi)什么用,我們很少自己去配置 ServletConfig。
  • LoadTimeWeaverAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) LoadTimeWeaver 對(duì)象,通過(guò)該對(duì)象可以獲取加載 Spring Bean 時(shí)織入的第三方模塊,如 AspectJ 等。
  • BeanClassLoaderAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) ClassLoader 對(duì)象,ClassLoader 能干嘛不需要我多說(shuō)了吧。
  • BeanNameAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè)當(dāng)前 Bean 的名稱。
  • ApplicationContextAware:實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) ApplicationContext 對(duì)象,通過(guò) ApplicationContext 可以獲取容器中的 Bean、環(huán)境等信息。

這是 Spring 中提供的一堆 Aware。

接下來(lái)松哥隨便寫個(gè)例子大家來(lái)看下 Aware 的用法。

2. BeanFactoryAware

實(shí)現(xiàn)該接口的對(duì)象可以獲取到一個(gè) BeanFactory 對(duì)象,通過(guò) BeanFactory 可以完成 Bean 的查詢等操作。這算是一個(gè)比較常見的 Aware 了,我們一起來(lái)看下。

這里為了省事,我就在 Spring Boot 中來(lái)和大家演示。

首先我們來(lái)定義一個(gè)簡(jiǎn)單的 UserService:

@Service
public?class?UserService?{
????public?void?hello()?{
????????System.out.println("hello?javaboy!");
????}
}

然后提供一個(gè)工具類:

@Component
public?class?BeanUtils?implements?BeanFactoryAware?{
????private?static?BeanFactory?beanFactory?=?null;

????@Override
????public?void?setBeanFactory(BeanFactory?beanFactory)?throws?BeansException?{
????????BeanUtils.beanFactory?=?beanFactory;
????}

????public?static?<T>?T?getBean(String?beanName)?{
????????return?(T)?beanFactory.getBean(beanName);
????}
}

有了這個(gè)工具類,接下來(lái)我們就可以在一個(gè)非 Spring 管理的 Bean 中,隨時(shí)隨地的查詢 Bean 了,像下面這樣:

UserService?userService?=?BeanUtils.getBean("userService");
userService.hello();

3. TienChin 項(xiàng)目實(shí)踐

為什么會(huì)有今天這篇文章呢?主要是在松哥最近做的 TienChin 項(xiàng)目中,有一個(gè)地方涉及到這塊知識(shí)點(diǎn)了,但是有的小伙伴不熟悉,因此就拎出來(lái)和大家梳理下。

在 TienChin 項(xiàng)目中,在記錄日志的時(shí)候,因?yàn)槿罩臼且粋€(gè)延遲任務(wù),所以提前準(zhǔn)備好了相關(guān)的 Bean 已經(jīng)注冊(cè)到 Spring 容器中了,像下面這樣:

@Configuration
public?class?ThreadPoolConfig?{

????/**
?????*?執(zhí)行周期性或定時(shí)任務(wù)
?????*/
????@Bean(name?=?"scheduledExecutorService")
????protected?ScheduledExecutorService?scheduledExecutorService()?{
????????return?new?ScheduledThreadPoolExecutor(corePoolSize,
????????????????new?BasicThreadFactory.Builder().namingPattern("schedule-pool-%d").daemon(true).build(),
????????????????new?ThreadPoolExecutor.CallerRunsPolicy())?{
????????????@Override
????????????protected?void?afterExecute(Runnable?r,?Throwable?t)?{
????????????????super.afterExecute(r,?t);
????????????????Threads.printException(r,?t);
????????????}
????????};
????}
}
@Component
public?final?class?SpringUtils?implements?BeanFactoryPostProcessor,?ApplicationContextAware?{
????/**
?????*?Spring應(yīng)用上下文環(huán)境
?????*/
????private?static?ConfigurableListableBeanFactory?beanFactory;

????private?static?ApplicationContext?applicationContext;

????@Override
????public?void?postProcessBeanFactory(ConfigurableListableBeanFactory?beanFactory)?throws?BeansException?{
????????SpringUtils.beanFactory?=?beanFactory;
????}

????@Override
????public?void?setApplicationContext(ApplicationContext?applicationContext)?throws?BeansException?{
????????SpringUtils.applicationContext?=?applicationContext;
????}

????/**
?????*?獲取對(duì)象
?????*
?????*?@param?name
?????*?@return?Object?一個(gè)以所給名字注冊(cè)的bean的實(shí)例
?????*?@throws?org.springframework.beans.BeansException
?????*/
????@SuppressWarnings("unchecked")
????public?static?<T>?T?getBean(String?name)?throws?BeansException?{
????????return?(T)?beanFactory.getBean(name);
????}

????/**
?????*?獲取類型為requiredType的對(duì)象
?????*
?????*?@param?clz
?????*?@return
?????*?@throws?org.springframework.beans.BeansException
?????*/
????public?static?<T>?T?getBean(Class<T>?clz)?throws?BeansException?{
????????T?result?=?(T)?beanFactory.getBean(clz);
????????return?result;
????}
}

而寫日志的異步任務(wù)工具類,并非一個(gè)容器,所以要通過(guò)這個(gè)工具類獲取相應(yīng)的 Bean,如下:

public?class?AsyncManager?{
????/**
?????*?操作延遲10毫秒
?????*/
????private?final?int?OPERATE_DELAY_TIME?=?10;

????/**
?????*?異步操作任務(wù)調(diào)度線程池
?????*/
????private?ScheduledExecutorService?executor?=?SpringUtils.getBean("scheduledExecutorService");

????/**
?????*?單例模式
?????*/
????private?AsyncManager()?{
????}

????private?static?AsyncManager?me?=?new?AsyncManager();

????public?static?AsyncManager?me()?{
????????return?me;
????}

????/**
?????*?執(zhí)行任務(wù)
?????*
?????*?@param?task?任務(wù)
?????*/
????public?void?execute(TimerTask?task)?{
????????executor.schedule(task,?OPERATE_DELAY_TIME,?TimeUnit.MILLISECONDS);
????}
}

有了 SpringUtils 我們就可以在一個(gè)非 Spring 容器所管理的 Bean 中,獲取到 Spring 容器中的 Bean 了。

到此這篇關(guān)于Spring通過(guò)工具類實(shí)現(xiàn)獲取容器中的Bean的文章就介紹到這了,更多相關(guān)Spring獲取Bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring?Cache+Redis緩存數(shù)據(jù)的實(shí)現(xiàn)示例

    Spring?Cache+Redis緩存數(shù)據(jù)的實(shí)現(xiàn)示例

    本文主要介紹了Spring?Cache+Redis緩存數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Java解壓縮zip - 解壓縮多個(gè)文件或文件夾實(shí)例

    Java解壓縮zip - 解壓縮多個(gè)文件或文件夾實(shí)例

    本篇文章主要介紹了Java解壓縮zip - 解壓縮多個(gè)文件或文件夾實(shí)例,非常具有實(shí)用價(jià)值,有需要的可以了解一下。
    2016-12-12
  • java 數(shù)學(xué)計(jì)算的具體使用

    java 數(shù)學(xué)計(jì)算的具體使用

    這篇文章主要介紹了java 數(shù)學(xué)計(jì)算的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 淺談線程的幾種可用狀態(tài)

    淺談線程的幾種可用狀態(tài)

    下面小編就為大家?guī)?lái)一篇淺談線程的幾種可用狀態(tài)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • ANSI,Unicode,BMP,UTF等編碼概念實(shí)例講解

    ANSI,Unicode,BMP,UTF等編碼概念實(shí)例講解

    這篇文章主要介紹了ANSI,Unicode,BMP,UTF等編碼概念實(shí)例講解,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • Java結(jié)合百度云存儲(chǔ)BCS代碼分享

    Java結(jié)合百度云存儲(chǔ)BCS代碼分享

    最近云是一個(gè)很熱門的新概念,仿佛任何東西只要跟云相關(guān)聯(lián),就立馬高大上起來(lái),額,我們也追隨潮流吧,項(xiàng)目中也結(jié)合一下云??!
    2014-10-10
  • Java中mybatis關(guān)于example類的使用詳解

    Java中mybatis關(guān)于example類的使用詳解

    這篇文章主要介紹了Java中mybatis中關(guān)于example類的使用詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • ssm實(shí)現(xiàn)視頻的上傳與播放的示例代碼

    ssm實(shí)現(xiàn)視頻的上傳與播放的示例代碼

    這篇文章主要介紹了ssm實(shí)現(xiàn)視頻的上傳與播放的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-04-04
  • SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    SpringBoot應(yīng)用能直接運(yùn)行java -jar的原因分析

    這篇文章主要介紹了SpringBoot應(yīng)用為什么能直接運(yùn)行java -jar,首先明確一點(diǎn),普通jar包是不能直接運(yùn)行的,比如工具類jar,要能運(yùn)行,至少得要一個(gè)main函數(shù)作為入口吧?本文給大家介紹了詳細(xì)的原因分析,需要的朋友可以參考下
    2024-03-03
  • MyBatis將查詢出的兩列數(shù)據(jù)裝配成鍵值對(duì)的操作方法

    MyBatis將查詢出的兩列數(shù)據(jù)裝配成鍵值對(duì)的操作方法

    這篇文章主要介紹了MyBatis將查詢出的兩列數(shù)據(jù)裝配成鍵值對(duì)的操作代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08

最新評(píng)論