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

Spring Aware源碼設(shè)計(jì)示例解析

 更新時(shí)間:2023年01月15日 15:38:54   作者:陳湯姆  
這篇文章主要為大家介紹了Spring Aware源碼設(shè)計(jì)示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

1. Aware介紹

前一篇講到了BeanPostProcessor的相關(guān)知識(shí),我們知道BeanPostProcessor是對(duì)整個(gè)容器中的Bean做前置和后置增強(qiáng)處理。這樣的實(shí)現(xiàn)方式限制了開(kāi)發(fā)者只能按照Spring提供的模板,對(duì)Bean做前置和后置的增強(qiáng),這樣雖然已經(jīng)很靈活了,但是如果開(kāi)發(fā)者想要對(duì)Spring中的Bean做更復(fù)雜的操作或者開(kāi)發(fā)者想要使用Spring中的BeanFactory、ClassLoader時(shí),這樣的方式明顯就不夠方便了,因此Spring也考慮到了這樣的情況,就提供了另外的方式提升Spring的擴(kuò)展性和靈活性,這種方式就是Aware。

單純說(shuō)Aware可能不熟悉,但是如果說(shuō)BeanNameAware、BeanFactoryAware那么是不是就知道這個(gè)Aware到底是何方神圣了。

接下來(lái)就說(shuō)一下Spring提供給開(kāi)發(fā)者Aware的這個(gè)功能。

Spring中Aware的源碼如下:

public interface Aware {
}

從源碼中可以看到Aware就是一個(gè)簡(jiǎn)單的接口,該接口是一個(gè)無(wú)實(shí)現(xiàn)的接口,一般看到這種接口可以都是作為最頂級(jí)的父類接口使用的,使用時(shí)一般都是instanceof判斷是否是頂級(jí)接口類型。

2. Aware類別

在Spring中Aware有幾個(gè)繼承接口,分別是:

  • BeanClassLoaderAware
  • BeanFactoryAware
  • BeanNameAware

2.1 BeanClassLoaderAware

首先是BeanClassLoaderAware接口,從字面意思翻譯就可以大概知道這是一個(gè)關(guān)于Bean的類加載器的接口,因此該接口的功能就聚焦在類加載器上。

BeanClassLoaderAware源碼如下:

public interface BeanClassLoaderAware extends Aware {
	//set方法,賦值ClassLoader方法
	void setBeanClassLoader(ClassLoader classLoader);
}

從源碼可以看到該接口只提供了一個(gè)setBeanClassLoader方法,該方法就是簡(jiǎn)單的設(shè)置Bean的類加載器的方法,所以從這個(gè)方法中就可以知道BeanClassLoaderAware就單純提供了一個(gè)賦值ClassLoader的方法,這里的接口并不會(huì)指定ClassLoader的接收方,因此接收方需要在實(shí)現(xiàn)該接口的實(shí)現(xiàn)類中指定,然后將ClassLoader賦值給實(shí)現(xiàn)類中的具體常量。

2.2 BeanFactoryAware

BeanFactoryAware接口,看到這個(gè)就立馬想到Spring中的BeanFactory,BeanFactory在Spring中是作為Bean的工廠,那么該接口一定是與BeanFactory相關(guān)的接口。

BeanFactoryAware源碼如下:

public interface BeanFactoryAware extends Aware {
    void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

從源碼中可以看到BeanFactoryAware跟BeanClassLoaderAware相似都只提供了一個(gè)set方法,該接口中只定義了setBeanFactory一個(gè)方法。

該接口中的方法 功能跟BeanClassLoaderAware功能相同,都是賦值,但是該接口賦值的是BeanFactory。

2.3 BeanNameAware

源碼如下:

public interface BeanNameAware extends Aware {
    void setBeanName(String name);
}

該接口功能同上。(說(shuō)實(shí)話實(shí)際開(kāi)發(fā)中沒(méi)用到過(guò)這個(gè),只用過(guò)前兩個(gè),所以我也沒(méi)搞懂該類到底可以干啥)。

2.4 ApplicationContextAware

該接口則是一個(gè)特別的接口了,因?yàn)樵摻涌诟叭齻€(gè)繼承Aware的接口不同,ApplicationContextAware并不是spring-bean中提供的接口,而是在spring-context中提供的接口,該接口是從spring-context包中提供的接口,該接口的作用也是跟前三個(gè)類似,并且大部分開(kāi)發(fā)者用的最多的也是這個(gè)。

源碼如下:

public interface ApplicationContextAware extends Aware {
    void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
}
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
    @Nullable
    String getId();
    String getApplicationName();
    String getDisplayName();
    long getStartupDate();
    @Nullable
    ApplicationContext getParent();
    AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}

源碼中也是簡(jiǎn)單的賦值操作,但是賦值的對(duì)象是ApplicationContext對(duì)象,對(duì)于這個(gè)對(duì)象使用Spring的一定不陌生。

可以這樣說(shuō):ApplicationContext給了開(kāi)發(fā)者最多的權(quán)限用于操作Bean。

從ApplicationContext源碼中也可以看到該接口繼承了ListableBeanFactory、HierarchicalBeanFactory、ApplicationEventPublisher等其它接口,這樣就將更多的Bean的權(quán)限通過(guò)ApplicationContext下放給開(kāi)發(fā)者?。ㄓ质潜籗pring的高靈活性折服的時(shí)刻)。

3. Aware的使用

@Component
public class MySpringAware implements BeanFactoryAware, BeanClassLoaderAware, ApplicationContextAware, BeanNameAware {
    private ApplicationContext applicationContext;
    private ListableBeanFactory beanFactory;
    private ClassLoader classLoader;
    private String beanName;
    /**
     * 獲取某個(gè)接口下的所有實(shí)現(xiàn)類
     *
     * @param filter
     */
    public void registryFilter(FilterProcessor filter) {
        Map<String, MyFilter> beans = beanFactory.getBeansOfType(MyFilter.class);
        beans.values().stream().sorted(AnnotationAwareOrderComparator.INSTANCE).forEach(filter::register);
    }
        /**
     * 獲取環(huán)境配置
     *
     * @return
     */
    public Environment getApplicationData() {
        return applicationContext.getEnvironment();
    }
    public ApplicationContext getApplicationContext() {
        return applicationContext;
    }
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        this.classLoader = classLoader;
    }
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (ListableBeanFactory) beanFactory;
    }
    @Override
    public void setBeanName(String s) {
        this.beanName = s;
    }
}
@Component
public class FilterProcessor {
    private final List<MyFilter> filterList = new ArrayList();
    public void register(MyFilter filter) {
        this.filterList.add(filter);
    }
    public List<MyFilter> getFilterList() {
        return filterList;
    }
}
public interface MyFilter {
    void doFilter();
}
@Component
@Order(1)
public class MyDemoFilter extends FilterProcessor implements MyFilter{
    @Override
    public void doFilter() {
        System.out.println("執(zhí)行第一個(gè)過(guò)濾器MyDemoFilter");
    }
}
@Component
@Order(2)
public class MyDemoFilter2 extends FilterProcessor implements MyFilter{
    @Override
    public void doFilter() {
        System.out.println("執(zhí)行第二個(gè)過(guò)濾器MyDemoFilter2");
    }
}

運(yùn)行結(jié)果:

以上的例子中通過(guò)MySpringAware實(shí)現(xiàn)了前文中說(shuō)到的幾個(gè)Aware,分別使用了其中的BeanFactory和ApplicationContext。這樣在MySpringAware中就可以使用我們定義的常量接收Spring容器中的BeanFactory、ClassLoader、ApplicationContext等功能。

4. Aware的作用

從以上的例子中可以看到,Aware為開(kāi)發(fā)者提供了插樁式的接口,開(kāi)發(fā)者只要實(shí)現(xiàn)該接口就可以獲得Spring容器的某些管理權(quán)。

比如BeanClassLoaderAware是獲得對(duì)Bean的類加載器的管理權(quán)。

BeanFactoryAware是活的對(duì)Bean工廠的管理權(quán)。

這樣插樁式的擴(kuò)展可以保證開(kāi)發(fā)者在使用時(shí)可以獲得Spring中某些功能的管理權(quán),方便開(kāi)發(fā)者對(duì)Spring的理解和使用,不需要復(fù)雜的實(shí)現(xiàn)就可以獲得Spring內(nèi)部的管理。

5. Aware的調(diào)用

前面說(shuō)完了Aware的介紹、類別和作用,最后來(lái)說(shuō)實(shí)現(xiàn)Aware相關(guān)接口的實(shí)現(xiàn)類在Spring中是如何被調(diào)用的。

實(shí)現(xiàn)Aware相關(guān)接口的實(shí)現(xiàn)類被調(diào)用的方式與前面講的BeanPostProcessor有一定區(qū)別。

區(qū)別如下:

BeanPostProcessor的調(diào)用:

  • 調(diào)用方式:注冊(cè)+讀取注冊(cè)列表(通過(guò)register.List和遍歷beanPostProcessorList)
  • 調(diào)用時(shí)機(jī):Bean執(zhí)行初始化函數(shù)(invokeInitMethods)之前或者之后

Aware的調(diào)用:

  • 調(diào)用方式:通過(guò)Bean是否實(shí)現(xiàn)了Aware/BeanClassLoaderAware/BeanFactoryAware,然后調(diào)用相應(yīng)的實(shí)現(xiàn)類的重寫(xiě)方法
  • 調(diào)用時(shí)機(jī):Bean執(zhí)行初始化函數(shù)(invokeInitMethods)之前且beanPostProcessor#before之前

源碼如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
    //初始化Bean的方法
	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                //調(diào)用Bean的Aware重寫(xiě)接口
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
            //調(diào)用Bean的Aware重寫(xiě)接口
			invokeAwareMethods(beanName, bean);
		}
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
            //調(diào)用BeanPostProcessor前置接口
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
		try {
            //調(diào)用Bean的初始化函數(shù)
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
            //調(diào)用BeanPostProcessor后置接口
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
	//調(diào)用Aware的實(shí)現(xiàn)
    private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }
}

區(qū)別梳理如下:

以AbstractAutowireCapableBeanFactory為主線梳理調(diào)用Aware接口的鏈路如下:

  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

對(duì)于ApplicationContextAware的調(diào)用鏈路梳理如下:

  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
  • org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
  • org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

根據(jù)以上的鏈路可以很清晰的看到ApplicationContextAware的調(diào)用實(shí)現(xiàn)。

以上就是Spring Aware源碼設(shè)計(jì)示例解析的詳細(xì)內(nèi)容,更多關(guān)于Spring Aware源碼設(shè)計(jì)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 輕松理解Java面試和開(kāi)發(fā)中的IoC(控制反轉(zhuǎn))

    輕松理解Java面試和開(kāi)發(fā)中的IoC(控制反轉(zhuǎn))

    在Java開(kāi)發(fā)中,IoC意 味著將你設(shè)計(jì)好的類交給系統(tǒng)去控制,而不是在你的類內(nèi)部控制。這稱為控制反轉(zhuǎn)。下文給大家介紹Java面試和開(kāi)發(fā)中的IoC(控制反轉(zhuǎn))知識(shí),需要的朋友參考下吧
    2017-07-07
  • URL @PathVariable 變量的匹配原理分析

    URL @PathVariable 變量的匹配原理分析

    這篇文章主要介紹了URL @PathVariable 變量的匹配原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Java實(shí)現(xiàn)多項(xiàng)式除法的代碼示例

    Java實(shí)現(xiàn)多項(xiàng)式除法的代碼示例

    今天小編就為大家分享一篇關(guān)于Java實(shí)現(xiàn)多項(xiàng)式除法的代碼示例,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-10-10
  • java多線程的同步方法實(shí)例代碼

    java多線程的同步方法實(shí)例代碼

    這篇文章主要介紹了 java多線程的同步方法實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • Java魔法堂之調(diào)用外部程序的方法

    Java魔法堂之調(diào)用外部程序的方法

    這篇文章主要介紹了Java魔法堂:調(diào)用外部程序的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-02-02
  • Mybatis執(zhí)行SQL時(shí)多了一個(gè)limit的問(wèn)題及解決方法

    Mybatis執(zhí)行SQL時(shí)多了一個(gè)limit的問(wèn)題及解決方法

    這篇文章主要介紹了Mybatis執(zhí)行SQL時(shí)多了一個(gè)limit的問(wèn)題及解決方法,Mybatis攔截器方法識(shí)別到配置中參數(shù)supportMethodsArguments 為ture時(shí)會(huì)分頁(yè)處理,本文結(jié)合示例代碼給大家講解的非常詳細(xì),需要的朋友可以參考下
    2022-10-10
  • spring-cloud-gateway動(dòng)態(tài)路由的實(shí)現(xiàn)方法

    spring-cloud-gateway動(dòng)態(tài)路由的實(shí)現(xiàn)方法

    這篇文章主要介紹了spring-cloud-gateway動(dòng)態(tài)路由的實(shí)現(xiàn)方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • win10下配置java環(huán)境變量的方法

    win10下配置java環(huán)境變量的方法

    這篇文章主要介紹了win10下配置java環(huán)境變量的方法,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02
  • SpringBoot整合Caffeine使用示例

    SpringBoot整合Caffeine使用示例

    Spring Boot 和 Caffeine 可以很容易地進(jìn)行整合,Caffeine 是一個(gè)現(xiàn)代化的 Java 緩存庫(kù),提供了高性能和靈活的緩存策略,本文給大家介紹了SpringBoot整合Caffeine使用示例,需要的朋友可以參考下
    2024-07-07
  • 關(guān)于Lambda表達(dá)式的方法引用和構(gòu)造器引用簡(jiǎn)的單示例

    關(guān)于Lambda表達(dá)式的方法引用和構(gòu)造器引用簡(jiǎn)的單示例

    這篇文章主要介紹了關(guān)于Lambda表達(dá)式的方法引用和構(gòu)造器引用簡(jiǎn)的單示例,方法引用與構(gòu)造器引用可以使?Lambda?表達(dá)式的代碼塊更加簡(jiǎn)潔<BR>,需要的朋友可以參考下
    2023-04-04

最新評(píng)論