ITPub博客

首页 > IT职业 > IT图书 > Spring Boot 自动配置

Spring Boot 自动配置

IT图书 作者:xtky_limi 时间:2021-09-09 10:05:03 0 删除 编辑

Spring Boot 自动配置

来看下 spring boot中自动配置的注解

@SuppressWarnings("deprecation")@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documented@Inherited@AutoConfigurationPackage@Import(EnableAutoConfigurationImportSelector.class)public @interface EnableAutoConfiguration {

    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    Class<?>[] exclude() default {};    /**
     * Exclude specific auto-configuration class names such that they will never be
     * applied.
     * @return the class names to exclude
     * @since 1.3.0
     */
    String[] excludeName() default {};

}
  • exclude() 可以排除一些自动配置的内容

  • excludeName 通过名称排除自动配置内容

再来看下,@EnableAutoConfiguration 是怎么处理自动配置的呢?

注意到@Import(EnableAutoConfigurationImportSelector.class)

public class EnableAutoConfigurationImportSelector
        extends AutoConfigurationImportSelector {    @Override
    protected boolean isEnabled(AnnotationMetadata metadata) {        if (getClass().equals(EnableAutoConfigurationImportSelector.class)) {            return getEnvironment().getProperty(
                    EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class,                    true);
        }        return true;
    }
}

}

再来看下 AutoConfigurationImportSelector ,主要是 接口的 ImportSelector 的实现

@Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {        if (!isEnabled(annotationMetadata)) {            return NO_IMPORTS;
        }        try {            //1、 自动配置的元数据 spring-autocomfigure-metadata.properties
            // 自动配置的开启条件
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
                    .loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = getAttributes(annotationMetadata);            // 获取设置的自动配置列表 spring.factories
            List<String> configurations = getCandidateConfigurations(annotationMetadata,
                    attributes);
            configurations = removeDuplicates(configurations);
            configurations = sort(configurations, autoConfigurationMetadata);            // 获取要排除的自动配置列表,可以通过 注解@EnableAutoConfiguration 的exclude和
             // 配置文件设置 spring.autoconfigure.exclude key的值
            Set<String> exclusions = getExclusions(annotationMetadata, attributes);
            checkExcludedClasses(configurations, exclusions);
            configurations.removeAll(exclusions);             // 通过 spring-autocomfigure-metadata.properties ConditionOnClass 条件进行过滤
            configurations = filter(configurations, autoConfigurationMetadata);
            fireAutoConfigurationImportEvents(configurations, exclusions);            return configurations.toArray(new String[configurations.size()]);
        }        catch (IOException ex) {            throw new IllegalStateException(ex);
        }
    }

看下 spring.factories 文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,
org.springframework.boot.autoconfigure.cloud.CloudAutoConfiguration,
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.ldap.LdapDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,
org.springframework.boot.autoconfigure.elasticsearch.jest.JestAutoConfiguration,
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,

再看下 spring framework中 ConfigurationClassParser 的处理方式,会解析 @Import 里的接口 ImportSelector 返回的所有配置类,那是怎么配置的呢,如 JpaRepositoriesAutoConfiguration

@Configuration@ConditionalOnBean(DataSource.class)@ConditionalOnClass(JpaRepository.class)@ConditionalOnMissingBean({ JpaRepositoryFactoryBean.class,
        JpaRepositoryConfigExtension.class })@ConditionalOnProperty(prefix = "spring.data.jpa.repositories", name = "enabled", havingValue = "true", matchIfMissing = true)@Import(JpaRepositoriesAutoConfigureRegistrar.class)@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)public class JpaRepositoriesAutoConfiguration {

}

从上面可以看到,有很多的@ConditionalOn**的注解,我们来看下 ConditionEvaluator这个 条件计算器,会去计算出当前这个配置类 是否要开启,而这些 @ConditionalOn** 是依赖于 @Conditional 这个注解,如  @ConditionalOnBean  最终是通过 Condition 接口来作条件选择

@Target({ ElementType.TYPE, ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)@Documented@Conditional(OnBeanCondition.class)public @interface ConditionalOnBean {    /**
     * The class type of bean that should be checked. The condition matches when any of
     * the classes specified is contained in the {@link ApplicationContext}.
     * @return the class types of beans to check
     */
    Class<?>[] value() default {};    /**
     * The class type names of bean that should be checked. The condition matches when any
     * of the classes specified is contained in the {@link ApplicationContext}.
     * @return the class type names of beans to check
     */
    String[] type() default {};    /**
     * The annotation type decorating a bean that should be checked. The condition matches
     * when any of the annotations specified is defined on a bean in the
     * {@link ApplicationContext}.
     * @return the class-level annotation types to check
     */
    Class<? extends Annotation>[] annotation() default {};    /**
     * The names of beans to check. The condition matches when any of the bean names
     * specified is contained in the {@link ApplicationContext}.
     * @return the name of beans to check
     */
    String[] name() default {};    /**
     * Strategy to decide if the application context hierarchy (parent contexts) should be
     * considered.
     * @return the search strategy
     */
    SearchStrategy search() default SearchStrategy.ALL;

}

Spring boot 的autoconfigure 是囊括了所有可以和spring 整合的项目,但大部分情况下,并不是所以的项目都会启用,通过 Condition和@Conditional 来判断条件

  1. 判断classPath 是否存在指定的类  @ConditionalOnClass

  2. 判断 ApplicationContext 中是否存在指定的 Bean  @ConditionalOnBean

  3. 配置环境中是否存在特定的配置项  @ConditionalOnProperty

  4. 配置环境中指定的配置项是否存在指定的值

禁用配置

当前 也是可以禁用某些我们不想要的默认配置,如上面加载时说到,会排除一些配置(exclude)

  1. 设置 @EnableAutoConfiguration  的exclude 配置

  2. 在配置文件增加 spring.autoconfigure.exclude 配置



作者:David_jim
链接:https://www.jianshu.com/p/7261521394e7



来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4383/viewspace-2815945/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2019-08-12

  • 博文量
    88
  • 访问量
    677