关于spring.factories的常用配置项说明

 更新时间:2024年07月13日 16:17:17   作者:飘零未归人  
这篇文章主要介绍了关于spring.factories的常用配置项说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

概述

spring.factories 实现是依赖 spring-core 包里的 SpringFactoriesLoader 类,这个类实现了检索 META-INF/spring.factories 文件,并获取指定接口的配置的功能。

Spring Factories机制提供了一种解耦容器注入的方式,帮助外部包(独立于spring-boot项目)注册Bean到spring boot项目容器中。

spring.factories 这种机制实际上是仿照 java 中的 SPI 扩展机制实现的。

Spring Factories机制原理

核心类SpringFactoriesLoader

从上文可知,Spring Factories机制通过META-INF/spring.factories文件获取相关的实现类的配置信息,而SpringFactoriesLoader的功能就是读取META-INF/spring.factories,并加载配置中的类。

SpringFactoriesLoader主要有两个方法:loadFactories和loadFactoryNames。

  • loadFactoryNames

用于按接口获取Spring Factories文件中的实现类的全称,其方法定义如下所示,其中参数factoryType指定了需要获取哪个接口的实现类,classLoader用于读取配置文件资源。

public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader)
  • loadFactories

用于按接口获取Spring Factories文件中的实现类的实例,其方法定义如下所示,其中参数factoryType指定了需要获取哪个接口的实现类,classLoader用于读取配置文件资源和加载类。

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader)

用法及配置

spring.factories 文件必须放在 resources 目录下的 META-INF 的目录下,否则不会生效。

如果一个接口希望配置多个实现类,可以用","分割。

BootstrapConfiguration

该配置项用于自动引入配置源,类似于spring-cloud的bootstrap和nacos的配置,通过指定的方式加载我们自定义的配置项信息。

该配置项配置的类必须是实现了PropertySourceLocator接口的类。

org.springframework.cloud.bootstrap.BootstrapConfiguration=\ xxxxxx.configure.config.ApplicationConfigure
public class ApplicationConfigure {

    @Bean
    @ConditionalOnMissingBean({CoreConfigPropertySourceLocator.class})
    public CoreConfigPropertySourceLocator configLocalPropertySourceLocator() {
        return new CoreConfigPropertySourceLocator();
    }
}

public class CoreConfigPropertySourceLocator implements PropertySourceLocator {
.....
}

ApplicationContextInitializer

该配置项用来配置实现了 ApplicationContextInitializer 接口的类,这些类用来实现上下文初始化

org.springframework.context.ApplicationContextInitializer=\
xxxxxx.config.TestApplicationContextInitializer
public class TestApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
 
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        System.out.println("TestApplicationContextInitializer.initialize() " + applicationContext);
    }
 
}

ApplicationListener

配置应用程序监听器,该监听器必须实现 ApplicationListener 接口。

它可以用来监听 ApplicationEvent 事件。

org.springframework.context.ApplicationListener=\
xxxxxxx.factories.listener.TestApplicationListener
@Slf4j
public class TestApplicationListener implements ApplicationListener<TestMessageEvent> {
 
    @Override
    public void onApplicationEvent(EmailMessageEvent event) {
        log.info("模拟消息事件... ");
        log.info("TestApplicationListener 接受到的消息:{}", event.getContent());
    }
}

AutoConfigurationImportListener

该配置项用来配置自动配置导入监听器,监听器必须实现 AutoConfigurationImportListener 接口。

该监听器可以监听 AutoConfigurationImportEvent 事件。

org.springframework.boot.autoconfigure.AutoConfigurationImportListener=\
xxxx.config.TestAutoConfigurationImportListener
public class TestAutoConfigurationImportListener implements AutoConfigurationImportListener {
    @Override
    public void onAutoConfigurationImportEvent(AutoConfigurationImportEvent event) {
        System.out.println("TestAutoConfigurationImportListener.onAutoConfigurationImportEvent() " + event);
    }
}

AutoConfigurationImportFilter

配置自动配置导入过滤器,过滤器必须实现 AutoConfigurationImportFilter 接口。

该过滤器用来过滤那些自动配置类可用。

org.springframework.boot.autoconfigure.AutoConfigurationImportFilter=\
xxxxxx.config.TestConfigurationCondition
public class TestConfigurationCondition implements AutoConfigurationImportFilter {

    @Override
    public boolean[] match(String[] autoConfigurationClasses, AutoConfigurationMetadata autoConfigurationMetadata) {
        System.out.println("TestConfigurationCondition.match() autoConfigurationClasses=" +  Arrays.toString(autoConfigurationClasses) + ", autoConfigurationMetadata=" + autoConfigurationMetadata);
        return new boolean[0];
    }
}

EnableAutoConfiguration

配置自动配置类。

这些配置类需要添加 @Configuration 注解,可用于注册bean。

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
xxxxx.config.TestConfiguration
@Configuration
public class MyConfiguration {
 
    public MyConfiguration() {
        System.out.println("MyConfiguration()");
    }

    @Bean
    public Testbean testbean(){
        return new Testbean()
    }
    
    //注册过滤器
     @Bean
    public TestFilter testFilter(){
        return new TestFilter()
    }
 
}

FailureAnalyzer

配置自定的错误分析类,该分析器需要实现 FailureAnalyzer 接口。

org.springframework.boot.diagnostics.FailureAnalyzer=\
xxxxx.config.TestFailureAnalyzer
/**
 * 自定义错误分析器
 */
public class TestFailureAnalyzer implements FailureAnalyzer {
 
    @Override
    public FailureAnalysis analyze(Throwable failure) {
        System.out.println("TestFailureAnalyzer.analyze() failure=" + failure);
        return new FailureAnalysis("TestFailureAnalyzer execute", "test spring.factories", failure);
    }
 
}

TemplateAvailabilityProvider

配置模板的可用性提供者,提供者需要实现 TemplateAvailabilityProvider 接口。

org.springframework.boot.autoconfigure.template.TemplateAvailabilityProvider=\
xxxxx.config.TestTemplateAvailabilityProvider
/**
 * 验证指定的模板是否支持
 */
public class TestTemplateAvailabilityProvider implements TemplateAvailabilityProvider {
 
    @Override
    public boolean isTemplateAvailable(String view, Environment environment, ClassLoader classLoader, ResourceLoader resourceLoader) {
        System.out.println("TestTemplateAvailabilityProvider.isTemplateAvailable() view=" + view + ", environment=" + environment + ", classLoader=" + classLoader + "resourceLoader=" + resourceLoader);
        return false;
    }

}

自定义Spring Factories机制

首先我们需要先定义两个模块,第一个模块A用于定义interface和获取interface的实现类。

代码如下:

package com.zhong.spring.demo.demo_7_springfactories;


public interface DemoService {
    void printName();
}


package com.zhong.spring.demo.demo_7_springfactories;

import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.util.List;


@Slf4j
@Service
public class DemoServiceFactory {
        @PostConstruct
        public void printService(){
            List<String> serviceNames = SpringFactoriesLoader.loadFactoryNames(DemoService.class,null);
            for (String serviceName:serviceNames){
                log.info("name:" + serviceName);
            }

            List<DemoService> services = SpringFactoriesLoader.loadFactories(DemoService.class,null);
            for (DemoService demoService:services){
                demoService.printName();
            }
        }
}

另一个模块B引入A模块,并实现DemoService类。并且配置spring.factories

代码如下:

package com.zhong.spring.usuldemo.impl;

import com.zhong.spring.demo.demo_7_springfactories.DemoService;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class DemoServiceImpl1 implements DemoService {
    @Override
    public void printName() {
        log.info("-----------DemoServiceImpl2------------");
    }
}


import com.zhong.spring.demo.demo_7_springfactories.DemoService;
import lombok.extern.slf4j.Slf4j;


@Slf4j
public class DemoServiceImpl2 implements DemoService {
    @Override
    public void printName() {
        log.info("-----------DemoServiceImpl2------------");
    }
}

spring.factory配置如下:

com.zhong.spring.demo.demo_7_springfactories.DemoService=\
com.zhong.spring.usuldemo.impl.DemoServiceImpl1,\
com.zhong.spring.usuldemo.impl.DemoServiceImpl2

启动模块B

得到以下日志;

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Boot与Spring Security的跨域问题解决方案

    Spring Boot与Spring Security的跨域问题解决方案

    跨域问题是指在Web开发中,浏览器出于安全考虑,限制了不同域名之间的资源访问,本文重点给大家介绍Spring Boot与Spring Security的跨域问题解决方案,感兴趣的朋友一起看看吧
    2023-09-09
  • Vert-x-通过异步的方式使用JDBC连接SQL

    Vert-x-通过异步的方式使用JDBC连接SQL

    在这篇文章中,我们将会看到怎样在vert.x应用中使用HSQL,当然也可以使用任意JDBC,以及使用vertx-jdbc-client提供的异步的API,这篇文章的代码在github
    2016-01-01
  • springboot 默认静态路径实例解析

    springboot 默认静态路径实例解析

    这篇文章主要介绍了springboot 默认静态路径实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • 详解Mybatis动态sql

    详解Mybatis动态sql

    MyBatis的动态SQL是基于OGNL表达式的,它可以帮助我们方便的在SQL语句中实现某些逻辑。本文给大家介绍Mybatis动态sql小结,感兴趣的朋友参考下
    2016-04-04
  • Java实现和电脑玩剪刀石头布游戏

    Java实现和电脑玩剪刀石头布游戏

    这篇文章主要为大家详细介绍了Java实现和电脑玩剪刀石头布游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • IDEA之web项目导入jar包方式

    IDEA之web项目导入jar包方式

    这篇文章主要介绍了IDEA之web项目导入jar包方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-05-05
  • java中文乱码之解决URL中文乱码问题的方法

    java中文乱码之解决URL中文乱码问题的方法

    这篇文章主要为大家分享了介绍了java中文乱码之解决URL中文乱码问题的方法,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • springboot2.0 配置时间格式化不生效问题的解决

    springboot2.0 配置时间格式化不生效问题的解决

    这篇文章主要介绍了springboot2.0 配置时间格式化不生效问题的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-09-09
  • AJAX Servlet实现数据异步交互的方法

    AJAX Servlet实现数据异步交互的方法

    本篇文章主要介绍了AJAX Servlet实现数据异步交互的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • Java面试问题知识点总结

    Java面试问题知识点总结

    本文主要介绍并且整理了Java面试知识点总结,,有需要的小伙伴可以参考下
    2017-04-04

最新评论