最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring-ImportSelector接口功能使用案例

 更新時(shí)間:2023年09月25日 15:53:53   作者:信仰_273993243  
ImportSelector接口是至spring中導(dǎo)入內(nèi)部類或者外部類的核心接口,只需要其定義的方法內(nèi)返回需要?jiǎng)?chuàng)建bean的class字符串就好了,這篇文章主要介紹了Spring-ImportSelector接口功能介紹,需要的朋友可以參考下

ImportSelector接口是至spring中導(dǎo)入內(nèi)部類或者外部類的核心接口,只需要其定義的方法內(nèi)返回需要?jiǎng)?chuàng)建bean的class字符串就好了,比如:當(dāng)我們引入一個(gè)外部share包,我們拿到里面的Class返回出去,就能得到這個(gè)bean,是多么神奇的事情,前提是這個(gè)類不是接口哦。

ImportSelector往往結(jié)合@Import注解一起使用,可以參考我的這篇文章@Import注解介紹

public interface ImportSelector {
	//返回類的字符串?dāng)?shù)組,也就是要?jiǎng)?chuàng)建的bean的className,比如userService.class.getName()
    //被創(chuàng)建的bean是在其他bean(@Component、@Service等注解修飾的Bean)創(chuàng)建之前創(chuàng)建的
	String[] selectImports(AnnotationMetadata importingClassMetadata);
}

二、使用案例

通過返回Class的字符串來創(chuàng)建bean

//定義一個(gè)業(yè)務(wù)類
public class UserServiceTest {
	public String getUserName(){
		return "測試";
	}
}
//實(shí)現(xiàn)ImportSelector接口
public class MyImportSelect implements ImportSelector {
	@Override
	public String[] selectImports(AnnotationMetadata importingClassMetadata) {
		//返回要注冊(cè)到Spring容器的Class集合
		return new String[]{UserServiceTest.class.getName()};
	}
}
//配置類
@Configuration
@Import(MyImportSelect.class) //導(dǎo)入我們實(shí)現(xiàn)ImportSelector的類。
public class AppConfigClassTest {
}

測試

public class MainTest {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext AnnotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfigClassTest.class);
		//這里我們不能通過“userServiceTest”來獲取bean,因?yàn)檫@個(gè)bean的name不是userServiceTest,而是userServiceTest.getClass().getName()
        //因?yàn)閎ean的別名成功器,只是針對(duì)像注解@Service等注解,會(huì)生成一個(gè)首字母小寫的BeanName
		UserServiceTest userServiceTest = AnnotationConfigApplicationContext.getBean(UserServiceTest.class);
		System.out.println(((UserServiceTest)userServiceTest).getUserName());
	}
}

下面說下源碼是怎么實(shí)現(xiàn)的,可以跳轉(zhuǎn)到@Import注解介紹

//這里就直接跳到ConfigurationClassPostProcessor處理@Import注解的邏輯上
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, 
                Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter, boolean checkForCircularImports) {
    //如果importCandidates為空直接return,為什么會(huì)有這個(gè),因?yàn)橄旅娲a可能會(huì)遞歸調(diào)用processImports,就比如Import一個(gè)類,這個(gè)類也帶了@Import注解,那就會(huì)在調(diào)用一次processImports方法
    if (importCandidates.isEmpty()) {
        return;
    }
    for (SourceClass candidate : importCandidates) {
        if (candidate.isAssignable(ImportSelector.class)) {
        	//1、import的類,實(shí)現(xiàn)了ImportSelector接口
            Class<?> candidateClass = candidate.loadClass();
            //利用反射Class實(shí)例化對(duì)象,這個(gè)對(duì)象不是代理對(duì)象不要搞混了。
            ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
                    this.environment, this.resourceLoader, this.registry);
            Predicate<String> selectorFilter = selector.getExclusionFilter();
            if (selectorFilter != null) {
                exclusionFilter = exclusionFilter.or(selectorFilter);
            }
            if (selector instanceof DeferredImportSelector) {
                this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
            } else {
            	//調(diào)用ImportSelector接口里面的selectImports方法,拿到返回值Class集合。在通過遞歸的方式嗲用processImports挨個(gè)解析每一個(gè)Class
                String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
                //轉(zhuǎn)成SourceClass集合
                Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
                //再次調(diào)用processImports方法
                processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
            }
        } else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
           。。。。。。
        } else {
            //3、ImportSelector和ImportBeanDefinitionRegistrar都沒有實(shí)現(xiàn)
            this.importStack.registerImport(currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
            //進(jìn)一步解析其他注解,比如@Component @Import等最后會(huì)把configClass注冊(cè)到Spring容器中。
            processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
        }
    }
}

看下instantiateClass方法做了什么

//創(chuàng)建實(shí)例對(duì)象
static <T> T instantiateClass(Class<?> clazz, Class<T> assignableTo, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry) {
	ClassLoader classLoader = 
	       (registry instanceof ConfigurableBeanFactory ? ((ConfigurableBeanFactory) registry).getBeanClassLoader() : resourceLoader.getClassLoader());
	T instance = (T) createInstance(clazz, environment, resourceLoader, registry, classLoader);
	ParserStrategyUtils.invokeAwareMethods(instance, environment, resourceLoader, registry, classLoader);
	return instance;
}
//調(diào)用createInstance方法創(chuàng)建實(shí)例對(duì)象
private static Object createInstance(Class<?> clazz, Environment environment, ResourceLoader resourceLoader, BeanDefinitionRegistry registry, @Nullable ClassLoader classLoader) {
	Constructor<?>[] constructors = clazz.getDeclaredConstructors();
	。。。。。。。
	return BeanUtils.instantiateClass(clazz);//通過Bean的工具類生成實(shí)例對(duì)象
}

到此這篇關(guān)于Spring-ImportSelector接口功能介紹的文章就介紹到這了,更多相關(guān)Spring ImportSelector接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringFactoriesLoader類作用詳解

    SpringFactoriesLoader類作用詳解

    SpringFactoriesLoader可以加載jar包下META-INF下的spring.factories,把相關(guān)接口的實(shí)現(xiàn)按照key,value的形式加載到內(nèi)存,一個(gè)接口的多個(gè)實(shí)現(xiàn)可以按照","進(jìn)行分割
    2022-10-10
  • java排序去重示例分享

    java排序去重示例分享

    這篇文章主要介紹了java排序去重示例,對(duì)String strs = "ZZZ BBB AAA OOO ZZZ AAA ZZZ"計(jì)算出現(xiàn)個(gè)數(shù),排序去重,需要的朋友可以參考下
    2014-02-02
  • Java中List  Set和Map之間的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java中List Set和Map之間的區(qū)別_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java集合的主要分為三種類型set集,list列表,map映射,接下來通過本文給大家詳細(xì)介紹java中l(wèi)ist、Set和Map之間的區(qū)別,需要的的朋友參考下吧
    2017-05-05
  • 詳解快速搭建Spring Boot+Spring MVC

    詳解快速搭建Spring Boot+Spring MVC

    本篇文章主要介紹了詳解快速搭建Spring Boot+Spring MVC,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-01-01
  • java編程FinalReference與Finalizer原理示例詳解

    java編程FinalReference與Finalizer原理示例詳解

    這篇文章主要為大家介紹了java編程FinalReference與Finalizer的核心原理以及示例源碼的分析詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2022-01-01
  • SpringBoot 中使用RabbtiMq?詳解

    SpringBoot 中使用RabbtiMq?詳解

    這篇文章主要介紹了SpringBoot 中使用RabbtiMq詳解,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)價(jià)值,需要的朋友可以參考一下
    2022-07-07
  • 詳解java中&和&&的區(qū)別

    詳解java中&和&&的區(qū)別

    這篇文章主要介紹了java中&和&&的區(qū)別,在java中比較常見的運(yùn)算符:&&(短路與)、&、||(短路或)、|,需要的朋友可以參考下
    2015-07-07
  • SpringBoot實(shí)現(xiàn)指標(biāo)監(jiān)控

    SpringBoot實(shí)現(xiàn)指標(biāo)監(jiān)控

    這篇文章主要介紹了SpringBoot實(shí)現(xiàn)指標(biāo)監(jiān)控方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • java以json格式向后臺(tái)服務(wù)器接口發(fā)送請(qǐng)求的實(shí)例

    java以json格式向后臺(tái)服務(wù)器接口發(fā)送請(qǐng)求的實(shí)例

    下面小編就為大家分享一篇java以json格式向后臺(tái)服務(wù)器接口發(fā)送請(qǐng)求的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • IDEA自動(dòng)補(bǔ)全返回值的三種快捷方式

    IDEA自動(dòng)補(bǔ)全返回值的三種快捷方式

    平常在編碼的過程中,可能需要調(diào)用第三方Api接口,這個(gè)過程中可能涉及到不太熟悉第三方Api接口的返回值類型,平常在編碼的過程中,可能需要調(diào)用第三方Api接口,這個(gè)過程中可能涉及到不太熟悉第三方Api接口的返回值類型,需要的朋友可以參考下
    2023-10-10

最新評(píng)論

平潭县| 庆阳市| 邢台县| 宕昌县| 郁南县| 兴化市| 江孜县| 天台县| 商水县| 收藏| 丰城市| 拉萨市| 永吉县| 衡山县| 遵义县| 桃园市| 肃南| 和龙市| 海原县| 灵石县| 普兰店市| 静宁县| 额济纳旗| 福清市| 潼南县| 英山县| 西平县| 建德市| 东乌珠穆沁旗| 子洲县| 城步| 友谊县| 晋州市| 西乌| 铜梁县| 青浦区| 清原| 衡山县| 大厂| 石首市| 和平区|