Aware接口

這個是spring-beans包中的概念欧聘,正常情況下我們使用bean是不需要考慮容器相關(guān)的特性的赐劣,所以基本在項目中不會接觸這個接口定页,但是這個接口是獲取容器相關(guān)屬性的核心迅耘,比如自己定一個一個bean,然后想在這個bean中獲取applicationContext或者beanName等屬性冤馏,那么我們就需要了解Aware接口相關(guān)的特性了日麸。我先說下源碼中如何獲取spring容器相關(guān)特性,然后再舉個例子說明下逮光。
1.spring容器啟動時會調(diào)用AbstractApplicationContext類的prepareBeanFactory方法代箭,其中會定義bean的后置處理器ApplicationContextAwareProcessor

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        beanFactory.setBeanClassLoader(this.getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver());
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
        beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
        beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
        beanFactory.registerResolvableDependency(ResourceLoader.class, this);
        beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
        beanFactory.registerResolvableDependency(ApplicationContext.class, this);
        if (beanFactory.containsBean("loadTimeWeaver")) {
            beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
            beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
        }

        if (!beanFactory.containsLocalBean("environment")) {
            beanFactory.registerSingleton("environment", this.getEnvironment());
        }

        if (!beanFactory.containsLocalBean("systemProperties")) {
            beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
        }

        if (!beanFactory.containsLocalBean("systemEnvironment")) {
            beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
        }

2.bean在初始化前會調(diào)用一次ApplicationContextAwareProcessor類的postProcessBeforeInitialization方法

public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
        AccessControlContext acc = null;
        if (System.getSecurityManager() != null && (bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware || bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware || bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
            acc = this.applicationContext.getBeanFactory().getAccessControlContext();
        }

        if (acc != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
                    return null;
                }
            }, acc);
        } else {
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }

3.注意postProcessBeforeInitialization方法中具體的invoke方法,如果實(shí)現(xiàn)Aware接口會繼續(xù)判斷實(shí)現(xiàn)了具體的什么接口涕刚,執(zhí)行對應(yīng)接口的方法嗡综。

private void invokeAwareInterfaces(Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware)bean).setEnvironment(this.applicationContext.getEnvironment());
            }

            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware)bean).setEmbeddedValueResolver(new ApplicationContextAwareProcessor.EmbeddedValueResolver(this.applicationContext.getBeanFactory()));
            }

            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware)bean).setResourceLoader(this.applicationContext);
            }

            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware)bean).setApplicationEventPublisher(this.applicationContext);
            }

            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware)bean).setMessageSource(this.applicationContext);
            }

            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

    }

舉個例子,MyApplicationContextAware實(shí)現(xiàn)了ApplicationContextAware接口,那么在初始化前會調(diào)用setApplicationContext方法杜漠,則可以拿到ApplicationContext

@Service
public class MyApplicationContextAware implements ApplicationContextAware {
    private ApplicationContext applicationContext;

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

    public ApplicationContext getApplicationContext(){
        return applicationContext;
    }
}

再舉個例子极景,可以拿到對應(yīng)bean的beanName

@Component
public class MyBeanNameAware implements BeanNameAware {
    private BeanName beanName;

    @Override
    public void setBeanName(BeanName beanName) throws BeansException {
        this.beanName = beanName;
    }

    public BeanName getBeanName(){
        return beanName;
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末察净,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子戴陡,更是在濱河造成了極大的恐慌塞绿,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件恤批,死亡現(xiàn)場離奇詭異,居然都是意外死亡裹赴,警方通過查閱死者的電腦和手機(jī)喜庞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來棋返,“玉大人延都,你說我怎么就攤上這事【ⅲ” “怎么了晰房?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長射沟。 經(jīng)常有香客問我殊者,道長,這世上最難降的妖魔是什么验夯? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任猖吴,我火速辦了婚禮,結(jié)果婚禮上挥转,老公的妹妹穿的比我還像新娘海蔽。我一直安慰自己,他們只是感情好绑谣,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布党窜。 她就那樣靜靜地躺著,像睡著了一般借宵。 火紅的嫁衣襯著肌膚如雪幌衣。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天暇务,我揣著相機(jī)與錄音泼掠,去河邊找鬼。 笑死垦细,一個胖子當(dāng)著我的面吹牛择镇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播括改,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼腻豌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起吝梅,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虱疏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后苏携,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體做瞪,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年右冻,在試婚紗的時候發(fā)現(xiàn)自己被綠了装蓬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡纱扭,死狀恐怖牍帚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情乳蛾,我是刑警寧澤暗赶,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站肃叶,受9級特大地震影響蹂随,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜被环,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一糙及、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧筛欢,春花似錦浸锨、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至剥险,卻和暖如春聪蘸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背表制。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工健爬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人么介。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓娜遵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親壤短。 傳聞我的和親對象是個殘疾皇子设拟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評論 2 359