zoukankan      html  css  js  c++  java
  • Spring Boot自动配置原理、实战

     

    Spring Boot自动配置原理

    Spring Boot的自动配置注解是@EnableAutoConfiguration, 从上面的@Import的类可以找到下面自动加载自动配置的映射。

    
     
    1. org.springframework.core.io.support.SpringFactoriesLoader.loadFactoryNames(Class<?>, ClassLoader)

    
     
    1. public static List<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {

    2.    String factoryClassName = factoryClass.getName();

    3.    try {

    4.        Enumeration<URL> urls = (classLoader != null ? classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :

    5.                lassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));

    6.        List<String> result = new ArrayList<String>();

    7.        while (urls.hasMoreElements()) {

    8.            URL url = urls.nextElement();

    9.            Properties properties = PropertiesLoaderUtils.loadProperties(new UrlResource(url));

    10.            String factoryClassNames = properties.getProperty(factoryClassName);

    11.            result.addAll(Arrays.asList(StringUtils.commaDelimitedListToStringArray(factoryClassNames)));

    12.        }

    13.        return result;

    14.    }

    15.    catch (IOException ex) {

    16.        throw new IllegalArgumentException("Unable to load [" + factoryClass.getName() +

    17.                "] factories from location [" + FACTORIES_RESOURCE_LOCATION + "]", ex);

    18.    }

    19. }

    这个方法会加载类路径及所有jar包下META-INF/spring.factories配置中映射的自动配置的类。

    
     
    1. /**

    2. * The location to look for factories.

    3. * <p>Can be present in multiple JAR files.

    4. */

    5. public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

    查看Spring Boot自带的自动配置的包: spring-boot-autoconfigure-1.5.6.RELEASE.jar,打开其中的META-INF/spring.factories文件会找到自动配置的映射。

    
     
    1. # Auto Configure

    2. org.springframework.boot.autoconfigure.EnableAutoConfiguration=

    3. org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,

    4. org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,

    5. org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,

    6. org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,

    7. org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,

    8. org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,

    9. org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,

    10. ...

    再来看看数据源自动配置的实现注解

    
     
    1. @Configuration

    2. @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })

    3. @EnableConfigurationProperties(DataSourceProperties.class)

    4. @Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })

    5. public class DataSourceAutoConfiguration {

    6. ...

    @Configuration,@ConditionalOnClass就是自动配置的核心,首先它得是一个配置文件,其次根据类路径下是否有这个类去自动配置。

    自动配置实战

    所以,了解了自动配置的原理,来自己实现一个自动配置的玩意其实很简单。

    添加配置类:

    
     
    1. import org.slf4j.Logger;

    2. import org.springframework.context.EnvironmentAware;

    3. import org.springframework.core.env.Environment;

    4. import com.oceanpayment.common.utils.logger.LoggerUtils;

    5. public class EnvConfig implements EnvironmentAware {

    6.    private final Logger logger = LoggerUtils.getLogger(this);

    7.    private Environment env;

    8.    public String getStringValue(String key) {

    9.        return env.getProperty(key);

    10.    }

    11.    public Long getLongValue(String key) {

    12.        String value = getStringValue(key);

    13.        try {

    14.            return Long.parseLong(value);

    15.        } catch (Exception e) {

    16.            logger.error("字符串转换Long失败:{} = {}", key, value);

    17.        }

    18.        return 0L;

    19.    }

    20.    public int getIntValue(String key) {

    21.        return getLongValue(key).intValue();

    22.    }

    23.    @Override

    24.    public void setEnvironment(Environment environment) {

    25.        this.env = environment;

    26.    }

    27. }

    添加自动配置类:

    
     
    1. import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;

    2. import org.springframework.context.annotation.Bean;

    3. import org.springframework.context.annotation.Configuration;

    4. import org.springframework.core.env.PropertyResolver;

    5. @Configuration

    6. @ConditionalOnClass(PropertyResolver.class)

    7. public class EnvAutoConfig {

    8.    @Bean

    9.    public EnvConfig envConfig() {

    10.        return new EnvConfig();

    11.    }

    12. }

    创建META-INF/spring.factories文件,添加自动配置映射:

    
     
    1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

    2. com.oceanpayment.common.config.env.EnvAutoConfig

    这样就搞定了。

    查看自动配置报告

    怎么查看自己加的自动配置类有没有被加载,或者查看所有自动配置激活的和未激活的可以通过以下几种试查看。

    1. spring-boot:run运行的在对话框Enviroment中加入debug=true变量 

    2. java -jar xx.jar --debug

    3. main方法运行,在VM Argumanets加入-Ddebug

    4. 直接在application文件中加入debug=true

    5. 如果集成了spring-boot-starter-actuator监控,通过autoconfig端点也可以查看。

    启动后会在控制台看到以下自动配置报告信息:

    
     
    1. =========================

    2. AUTO-CONFIGURATION REPORT

    3. =========================

    4. Positive matches:

    5. -----------------

    6.   AopAutoConfiguration matched:

    7.      - @ConditionalOnClass found required classes 'org.springframework.context.annotation.EnableAspectJAutoProxy', 'org.aspectj.lang.annotation.Aspect', 'org.aspectj.lang.reflect.Advice'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

    8.      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

    9.   ...

    10.   EnvAutoConfig matched:

    11.      - @ConditionalOnClass found required class 'org.springframework.core.env.PropertyResolver'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

    12.   ErrorMvcAutoConfiguration matched:

    13.      - @ConditionalOnClass found required classes 'javax.servlet.Servlet', 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)

    14.      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)

    15.   ErrorMvcAutoConfiguration#basicErrorController matched:

    16.      - @ConditionalOnMissingBean (types: org.springframework.boot.autoconfigure.web.ErrorController; SearchStrategy: current) did not find any beans (OnBeanCondition)

    17.   ...

    18. Negative matches:

    19. -----------------

    20.   ActiveMQAutoConfiguration:

    21.      Did not match:

    22.         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

    23.   AopAutoConfiguration.JdkDynamicAutoProxyConfiguration:

    24.      Did not match:

    25.         - @ConditionalOnProperty (spring.aop.proxy-target-class=false) found different value in property 'proxy-target-class' (OnPropertyCondition)

    26.   ArtemisAutoConfiguration:

    27.      Did not match:

    28.         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory' (OnClassCondition)

    29.   BatchAutoConfiguration:

    30.      Did not match:

    31.         - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)

    32.   ...

    Positive matches:已经启用的自动配置

    Negative matches:未启用的自动配置

    从报告中看到自己添加的EnvAutoConfig已经自动配置了。

  • 相关阅读:
    CSS 图像左右对齐
    CSS 图像居中对齐
    CSS 图像大小
    CSS表单3 光标样式 (每个位置鼠标放上去的样式不同)
    CSS表单2 组件排版
    对于下一代互联网的畅想
    VMware nat可以 桥接不可以
    jsp 入门
    flask_whooshalchemyplus 搜索
    PasswordField 无法设置默认值
  • 原文地址:https://www.cnblogs.com/xiang--liu/p/9710174.html
Copyright © 2011-2022 走看看