ApplicationContextAware使用理解

問題背景

在我們的web程序中空扎,用spring來管理各個實例(bean), 有時在程序中為了使用已被實例化的bean, 通常會用到這樣的代碼:

ApplicationContext appContext = new ClassPathXmlApplicationContext("applicationContext-common.xml");  
AbcService abcService = (AbcService)appContext.getBean("abcService");  

但是這樣就會存在一個問題:因為它會重新裝載applicationContext-common.xml并實例化上下文bean延窜,如果有些線程配置類也是在這個配置文件中,那么會造成做相同工作的的線程會被啟兩次袱箱。一次是web容器初始化時啟動,另一次是上述代碼顯示的實例化了一次。當于重新初始化一遍9敬濉!N冒场懈涛!這樣就產(chǎn)生了冗余。

解決方法

不用類似new ClassPathXmlApplicationContext()的方式泳猬,從已有的spring上下文取得已實例化的bean批钠。通過ApplicationContextAware接口進行實現(xiàn)。

當一個類實現(xiàn)了這個接口(ApplicationContextAware)之后得封,這個類就可以方便獲得ApplicationContext中的所有bean埋心。換句話說,就是這個類可以直接獲取spring配置文件中忙上,所有有引用到的bean對象拷呆。

ApplicationContextAware怎么用

(1)方法類AppUtil實現(xiàn)ApplicationContextAware接口

@Component
public class AppUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;
    
    @Override
    public void setApplicationContext(ApplicationContext arg0) throws BeansException {
        applicationContext = arg0;
    }

    public static Object getObject(String id) {
        Object object = null;
        object = applicationContext.getBean(id);
        return object;
    }
}

【備注】

(1)在spring的配置文件中,注冊方法類AppUtil晨横。之所以方法類AppUtil能夠靈活自如地獲取ApplicationContext洋腮,就是因為spring能夠為我們自動地執(zhí)行了setApplicationContext。但是手形,spring不會無緣無故地為某個類執(zhí)行它的方法的啥供,所以,就很有必要通過注冊方法類AppUtil的方式告知spring有這樣子一個類的存在库糠。這里我們使用@Component來進行注冊伙狐,或者我們也可以像下面這樣在配置文件聲明bean:

<bean id="appUtil" class="com.htsoft.core.util.AppUtil"/>

(2)加載Spring配置文件時,如果Spring配置文件中所定義的Bean類實現(xiàn)了ApplicationContextAware 接口瞬欧,那么在加載Spring配置文件時贷屎,會自動調(diào)用ApplicationContextAware 接口中的

public void setApplicationContext(ApplicationContext context) throws BeansException

方法,獲得ApplicationContext對象,ApplicationContext對象是由spring注入的艘虎。前提必須在Spring配置文件中指定該類唉侄。

(3)使用靜態(tài)的成員ApplicationContext類型的對象。

使用場景備注

從ApplicationContextAware獲取ApplicationContext上下文的情況野建,僅僅適用于當前運行的代碼和已啟動的Spring代碼處于同一個Spring上下文属划,否則獲取到的ApplicationContext是空的恬叹。

比如我要為當前系統(tǒng)加入一個定時任務(wù),定時刷新Memcache緩存同眯。這個定時任務(wù)框架是公司的框架绽昼,下面是我的ApplicationContextAware 接口實現(xiàn)類:

@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private static ApplicationContext applicationContext;//聲明一個靜態(tài)變量保存

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("applicationContext正在初始化,application:"+appContext);
        this.applicationContext=applicationContext;
    }

    public static <T> T getBean(Class<T> clazz){
        if(applicationContext==null){
            System.out.println("applicationContext是空的");
        }else{
            System.out.println("applicationContext不是空的");
        }
        return applicationContext.getBean(clazz);
    }

    public static ApplicationContext getApplicationContext(){
        return applicationContext;
    }
}

定時任務(wù)類如下,定時任務(wù)初始化的時候须蜗,首先會調(diào)用作業(yè)類的public static Object getObject()方法返回作業(yè)類的實例硅确。

@Component
public class RemoteCacheJob extends AbstractSaturnJavaJob {

    @Autowired
    private AdsRemoteCacheJob adsRemoteCacheJob;

    @Autowired
    private ILogService logService;

  // 實例化的過程:系統(tǒng)會首先調(diào)用作業(yè)類的public static Object getObject()方法,
  // 如果返回為null明肮,則調(diào)用作業(yè)類的無參構(gòu)造方法來實例化菱农;否則直接使用getObject()方法返回的對象作為作業(yè)類實例。
    public static Object getObject() {
        return ApplicationContextUtil.getBean(RemoteCacheJob .class);
    }

    @Override
    public void handleJavaJob(String jobName, Integer shardItem, String shardParam, SaturnJobExecutionContext shardingContext)
            throws InterruptedException {
          System.out.println("處理定時任務(wù)");
    }
}

啟動項目柿估,Spring容器進行初始化大莫,可以看到已經(jīng)初始化了ApplicationContext :

然后運行定時任務(wù)插件,首先去獲取ApplicationContext官份,但是此時的applicationContext是空的:

很顯然只厘,定時任務(wù)是沒辦法獲取到項目所在Spring容器啟動之后的ApplicationContext。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舅巷,一起剝皮案震驚了整個濱河市羔味,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌钠右,老刑警劉巖赋元,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異飒房,居然都是意外死亡搁凸,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門狠毯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來护糖,“玉大人,你說我怎么就攤上這事嚼松〉樟迹” “怎么了?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵献酗,是天一觀的道長寝受。 經(jīng)常有香客問我,道長罕偎,這世上最難降的妖魔是什么很澄? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上甩苛,老公的妹妹穿的比我還像新娘忙干。我一直安慰自己,他們只是感情好浪藻,可當我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著乾翔,像睡著了一般爱葵。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上反浓,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天萌丈,我揣著相機與錄音,去河邊找鬼雷则。 笑死辆雾,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的月劈。 我是一名探鬼主播度迂,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼猜揪!你這毒婦竟也來了惭墓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤而姐,失蹤者是張志新(化名)和其女友劉穎腊凶,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體拴念,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡钧萍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了政鼠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片风瘦。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖公般,靈堂內(nèi)的尸體忽然破棺而出弛秋,到底是詐尸還是另有隱情,我是刑警寧澤俐载,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布蟹略,位于F島的核電站,受9級特大地震影響遏佣,放射性物質(zhì)發(fā)生泄漏挖炬。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一状婶、第九天 我趴在偏房一處隱蔽的房頂上張望意敛。 院中可真熱鬧馅巷,春花似錦、人聲如沸草姻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽撩独。三九已至敞曹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間综膀,已是汗流浹背澳迫。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剧劝,地道東北人橄登。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像讥此,于是被迫代替她去往敵國和親拢锹。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理萄喳,服務(wù)發(fā)現(xiàn)面褐,斷路器,智...
    卡卡羅2017閱讀 134,657評論 18 139
  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器取胎,...
    simoscode閱讀 6,714評論 2 22
  • 1.1 Spring IoC容器和bean簡介 本章介紹了Spring Framework實現(xiàn)的控制反轉(zhuǎn)(IoC)...
    起名真是難閱讀 2,583評論 0 8
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,811評論 6 342
  • 小的時候展哭,我算是父母眼中的乖孩子,別人眼中的"別人家的孩子"闻蛀,一直也是和很多聽話的孩子一起玩匪傍,一起長大的。今天觉痛,和...
    艾米文_米來閱讀 201評論 0 0