Spring Boot 自动配置的实现

网友投稿 256 2023-01-24


Spring Boot 自动配置的实现

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)) {

reqsKeLrRIturn NO_IMPORTS;

}

try {

//1http://、 自动配置的元数据 spring-autocomfigure-metadata.properties

// 自动配置的开启条件

AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader

.loadMetadata(this.beanClassLoader);

AnnotationAttributes attributes = getAttributes(annotationMetadata);

// 获取设置的自动配置列表 spring.factories

List configurations = getCandidateConfigurations(annotationMetadata,

attributes);

configurations = removeDuplicates(configurations);

configurations = sort(configurations, autoConfigurationMetadata);

// 获取要排除的自动配置列表,可以通过 注解@EnableAutoConfiguration 的exclude和

// 配置文件设置 spring.autoconfigure.exclude key的值

Set exclusions = getExclusions(annotationMetadata, attributes);

http:// 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 来判断条件

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

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

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

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

禁用配置

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

设置 @EnableAutoConfiguration 的exclude 配置

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Mybatis查询语句结果集的总结大全
下一篇:新一代接口自动化测试(新一代接口自动化测试方法)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~