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

SpringFactoriesLoader類作用詳解

 更新時(shí)間:2022年10月26日 14:45:22   作者:沫洺  
SpringFactoriesLoader可以加載jar包下META-INF下的spring.factories,把相關(guān)接口的實(shí)現(xiàn)按照key,value的形式加載到內(nèi)存,一個(gè)接口的多個(gè)實(shí)現(xiàn)可以按照","進(jìn)行分割

SpringFactoriesLoader類

介紹

SpringFactoriesLoader類的主要作用是通過類路徑下的META-INF/spring.factories文件獲取工廠類接口的實(shí)現(xiàn)類,初始化并保存在緩存中,以供Springboot啟動(dòng)過程中各個(gè)階段的調(diào)用。Spring的自動(dòng)化配置功能,也與此息息相關(guān)。

SpringFactoriesLoader 工廠加載機(jī)制是 Spring 內(nèi)部提供的一個(gè)約定俗成的加載方式,只需要在模塊的 META-INF/spring.factories 文件中,以 Properties 類型(即 key-value 形式)配置,就可以將相應(yīng)的實(shí)現(xiàn)類注入 Spirng 容器中。

Properties類型格式:

key:value

  • key:是全限定名(抽象類|接口)
  • value:是實(shí)現(xiàn)類,多個(gè)實(shí)現(xiàn)類通過逗號進(jìn)行分割

spring boot類路徑下: META-INFO/spring.factories

方法

返回值方法描述
<T>List<T>loadFactories(Class<T> factoryType,@Nullable ClassLoader classLoader)靜態(tài)方法 根據(jù)接口獲取其實(shí)現(xiàn)類的實(shí)例 該方法返回的是實(shí)現(xiàn)類對象列表
List<String>loadFactoryNames(Class<?>) factoryType,@Nullable ClassLoader classLoader)公共靜態(tài)方法 根據(jù)接口獲取其實(shí)現(xiàn)類的名稱 該方法返回的是實(shí)現(xiàn)類的類名的列表
public final class SpringFactoriesLoader {
    //文件位置,可以存在多個(gè)JAR文件中
    public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
    //用來緩存MultiValueMap對象
    private static final Map<ClassLoader, MultiValueMap<String, String>> cache = new ConcurrentReferenceHashMap<>();
    private SpringFactoriesLoader() {
    }
    /**
     * 根據(jù)給定的類型加載并實(shí)例化工廠的實(shí)現(xiàn)類
     */
    public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
        Assert.notNull(factoryType, "'factoryType' must not be null");
        //獲取類加載器
        ClassLoader classLoaderToUse = classLoader;
        if (classLoaderToUse == null) {
            classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
        }
        //加載類的全限定名
        List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
        if (logger.isTraceEnabled()) {
            logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
        }
        //創(chuàng)建一個(gè)存放對象的List
        List<T> result = new ArrayList<>(factoryImplementationNames.size());
        for (String factoryImplementationName : factoryImplementationNames) {
            //實(shí)例化Bean,并將Bean放入到List集合中
            result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
        }
        //對List中的Bean進(jìn)行排序
        AnnotationAwareOrderComparator.sort(result);
        return result;
    }
    /**
     * 根據(jù)給定的類型加載類路徑的全限定名
     */
    public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
        //獲取名稱
        String factoryTypeName = factoryType.getName();
        //加載并獲取所有META-INF/spring.factories中的value
        return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList());
    }
    private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
        //根據(jù)類加載器從緩存中獲取,如果緩存中存在,就直接返回,如果不存在就去加載
        MultiValueMap<String, String> result = cache.get(classLoader);
        if (result != null) {
            return result;
        }
        try {
            //獲取所有JAR及classpath路徑下的META-INF/spring.factories的路徑
            Enumeration<URL> urls = (classLoader != null ?
                    classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
                    ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
            result = new LinkedMultiValueMap<>();
            //遍歷所有的META-INF/spring.factories的路徑
            while (urls.hasMoreElements()) {
                URL url = urls.nextElement();
                UrlResource resource = new UrlResource(url);
                //將META-INF/spring.factories中的key value加載為Prpperties對象
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                for (Map.Entry<?, ?> entry : properties.entrySet()) {
                    //key名稱
                    String factoryTypeName = ((String) entry.getKey()).trim();
                    for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
                        //以factoryTypeName為key,value為值放入map集合中
                        result.add(factoryTypeName, factoryImplementationName.trim());
                    }
                }
            }
            //放入到緩存中 
            cache.put(classLoader, result);
            return result;
        }
        catch (IOException ex) {
            throw new IllegalArgumentException("Unable to load factories from location [" +
                    FACTORIES_RESOURCE_LOCATION + "]", ex);
        }
    }
    //實(shí)例化Bean對象
    @SuppressWarnings("unchecked")
    private static <T> T instantiateFactory(String factoryImplementationName, Class<T> factoryType, ClassLoader classLoader) {
        try {
            Class<?> factoryImplementationClass = ClassUtils.forName(factoryImplementationName, classLoader);
            if (!factoryType.isAssignableFrom(factoryImplementationClass)) {
                throw new IllegalArgumentException(
                        "Class [" + factoryImplementationName + "] is not assignable to factory type [" + factoryType.getName() + "]");
            }
            return (T) ReflectionUtils.accessibleConstructor(factoryImplementationClass).newInstance();
        }
        catch (Throwable ex) {
            throw new IllegalArgumentException(
                "Unable to instantiate factory class [" + factoryImplementationName + "] for factory type [" + factoryType.getName() + "]",
                ex);
        }
    }
}

測試

resources下新建META-INF/spring.factories

com.moming.service.IStudentService=\
com.moming.service.impl.StudentServiceImpl1,\
com.moming.service.impl.StudentServiceImpl2

創(chuàng)建業(yè)務(wù)層接口及實(shí)現(xiàn)類

service/IStudentService

service/impl/StudentServiceImpl1

service/impl/StudentServiceImpl2

測試

@SpringBootApplication
public class App{
    public static void main(String[] args) {
        //SpringApplication.run(App.class, args);
        List<String> names = SpringFactoriesLoader.loadFactoryNames(IStudentService.class, ClassUtils.getDefaultClassLoader());
        for (String name : names) {
            System.out.println(name);
        }
        System.out.println("===================================");
        List<IStudentService> iStudentServices = SpringFactoriesLoader.loadFactories(IStudentService.class, ClassUtils.getDefaultClassLoader());
        for (IStudentService iStudentService : iStudentServices) {
            System.out.println(iStudentService);
            System.out.println(iStudentService.game());
        }
    }
}

通過以上可以證明,SpringFactoriesLoader會(huì)尋找jar包中配置META-INF下的spring.factories配置文件相應(yīng)Key的value,并根據(jù)需要實(shí)例化

到此這篇關(guān)于SpringFactoriesLoader類作用詳解的文章就介紹到這了,更多相關(guān)SpringFactoriesLoader內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot定制三種錯(cuò)誤頁面及錯(cuò)誤數(shù)據(jù)方法示例

    SpringBoot定制三種錯(cuò)誤頁面及錯(cuò)誤數(shù)據(jù)方法示例

    Spring Boot提供的默認(rèn)異常處理機(jī)制通常并不一定適合我們實(shí)際的業(yè)務(wù)場景,因此,我們通常會(huì)根據(jù)自身的需要對Spring Boot全局異常進(jìn)行統(tǒng)一定制,例如定制錯(cuò)誤頁面,定制錯(cuò)誤數(shù)據(jù)等。本文主要介紹了SpringBoot三種自定義錯(cuò)誤頁面的實(shí)現(xiàn),快來學(xué)習(xí)吧
    2021-12-12
  • 利用Java實(shí)現(xiàn)在PDF中添加工具提示

    利用Java實(shí)現(xiàn)在PDF中添加工具提示

    這篇文章主要介紹了如何通過Java在PDF中添加工具提示,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的參考價(jià)值,感興趣的可以學(xué)習(xí)一下
    2022-01-01
  • 基于hibernate實(shí)現(xiàn)的分頁技術(shù)實(shí)例分析

    基于hibernate實(shí)現(xiàn)的分頁技術(shù)實(shí)例分析

    這篇文章主要介紹了基于hibernate實(shí)現(xiàn)的分頁技術(shù),結(jié)合實(shí)例形式分析了Hibernate分頁技術(shù)的原理,實(shí)現(xiàn)步驟與相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2016-03-03
  • Spring實(shí)現(xiàn)泛型注入的示例詳解

    Spring實(shí)現(xiàn)泛型注入的示例詳解

    Spring?4.0版本中更新了很多新功能,其中比較重要的一個(gè)就是對帶泛型的Bean進(jìn)行依賴注入的支持。本文將通過實(shí)例詳細(xì)講講Spring如何實(shí)現(xiàn)泛型注入,需要的可以參考一下
    2022-07-07
  • 自定義指定路由上的Gateway過濾器工廠詳解

    自定義指定路由上的Gateway過濾器工廠詳解

    這篇文章主要介紹了自定義指定路由上的Gateway過濾器工廠詳解,gateway是Spring?Cloud中的一個(gè)網(wǎng)關(guān)服務(wù),gateway可以使用服務(wù)注冊中心進(jìn)行服務(wù)發(fā)現(xiàn)和負(fù)載均衡,同時(shí)還可以配置斷言來判斷請求是否符合路由規(guī)則,需要的朋友可以參考下
    2023-09-09
  • jvm內(nèi)存溢出解決方法(jvm內(nèi)存溢出怎么解決)

    jvm內(nèi)存溢出解決方法(jvm內(nèi)存溢出怎么解決)

    jvm內(nèi)存溢出解決方法,詳細(xì)內(nèi)容看下面解釋
    2013-12-12
  • MyBatis中SqlSession實(shí)現(xiàn)增刪改查案例

    MyBatis中SqlSession實(shí)現(xiàn)增刪改查案例

    這篇文章主要介紹了MyBatis中SqlSession實(shí)現(xiàn)增刪改查案例,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • Java8中接口的新特性使用指南

    Java8中接口的新特性使用指南

    接口改動(dòng)一下就要修改對應(yīng)的實(shí)現(xiàn)類,為了兼容老接口,Java8新增了默認(rèn)方法和靜態(tài)方法,下面這篇文章主要給大家介紹了關(guān)于Java8中接口新特性的相關(guān)資料,需要的朋友可以參考下
    2021-11-11
  • 重學(xué)SpringBoot3之日志Logging使用方式

    重學(xué)SpringBoot3之日志Logging使用方式

    在日常開發(fā)中會(huì)遇到不同的異常,日志方便我們?nèi)ヅ挪樘幚?這篇文章主要給大家介紹了關(guān)于重學(xué)SpringBoot3之日志Logging使用方式的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • 解決RedisTemplate調(diào)用increment報(bào)錯(cuò)問題

    解決RedisTemplate調(diào)用increment報(bào)錯(cuò)問題

    這篇文章主要介紹了解決RedisTemplate調(diào)用increment報(bào)錯(cuò)問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-11-11

最新評論

普定县| 和静县| 肇源县| 普安县| 法库县| 团风县| 长乐市| 三台县| 清涧县| 宝丰县| 横峰县| 云和县| 禹州市| 霞浦县| 类乌齐县| 永修县| 楚雄市| 昭苏县| 永泰县| 永川市| 葵青区| 普陀区| 尚志市| 盘山县| 山阳县| 南江县| 罗源县| 清河县| 黄骅市| 清苑县| 内丘县| 德保县| 济南市| 弥勒县| 辉南县| 秦安县| 仪征市| 区。| 易门县| 新余市| 渝北区|