1.启用自动化配置
- 在springboot中使用@EnableAutoConfiguration注解开启,而@EnableAutoConfiguration集成在了@SpringBootApplication中,所以springboot项目中不需要显示配置@EnableAutoConfiguration,默认开启了自动化配置;
- @EnableAutoConfiguration集成了@AutoConfigurationPackage,收集spring扫描的包名;
- @EnableAutoConfiguration导入了AutoConfigurationImportSelector类(springboot-EnableXX启用配置原理),AutoConfigurationImportSelector注册所有自动化配置相关的配置类(XXAutoConfiguration);
2.@AutoConfigurationPackage
作用:收集spring扫描的包名/类。由于没有配置basePackages和basePackageClasses,实际上是把标注@AutoConfigurationPackage类所在的包添加到了spring扫描的包中;
Registrar注册包名
- AutoConfigurationPackage导入了AutoConfigurationPackages的内部类Registrar;
- ImportBeanDefinitionRegistrar接口registerBeanDefinitions方法使用registry注册相关bean,通常是注册一些配置类;
- DeterminableImports接口,与ImportSelector/ImportBeanDefinitionRegistrar一起使用时,描述ImportSelector/ImportBeanDefinitionRegistrar注册的bean名称;
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
//**调用register方法注册包名
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
//**根据注解元数据创建PackageImports获取包名,然后注册
register(registry, new PackageImports(metadata).getPackageNames().toArray(new String[0]));
}
//**描述ImportBeanDefinitionRegistrar注册的包名;
@Override
public Set<Object> determineImports(AnnotationMetadata metadata) {
return Collections.singleton(new PackageImports(metadata));
}
}
PackageImports获取需注册包名
private static final class PackageImports {
//**需要注册的包名
private final List<String> packageNames;
//**构造函数,获取需要注册的包名
PackageImports(AnnotationMetadata metadata) {
//**获取AutoConfigurationPackage注解元数据
AnnotationAttributes attributes = AnnotationAttributes
.fromMap(metadata.getAnnotationAttributes(AutoConfigurationPackage.class.getName(), false));
List<String> packageNames = new ArrayList<>();
//**获取配置的basePackages,实际上没有配置
for (String basePackage : attributes.getStringArray("basePackages")) {
packageNames.add(basePackage);
}
//**获取配置的basePackageClasses,实际上没有配置
for (Class<?> basePackageClass : attributes.getClassArray("basePackageClasses")) {
packageNames.add(basePackageClass.getPackage().getName());
}
//**如果basePackages和basePackageClasses都没有配置,则把标注@AutoConfigurationPackage类所在的包添加到packageNames中
if (packageNames.isEmpty()) {
//**使用className.lastIndexOf(".")截取类所在的包名
packageNames.add(ClassUtils.getPackageName(metadata.getClassName()));
}
this.packageNames = Collections.unmodifiableList(packageNames);
}
List<String> getPackageNames() {
return this.packageNames;
}
//**DeterminableImports接口返回的对象必须实现hashCode和equals方法
public boolean equals(Object obj) { ... }
public int hashCode() { ... }
public String toString() { ... }
}
register注册包名逻辑
public static void register(BeanDefinitionRegistry registry, String... packageNames) {
//**如果已经注册了AutoConfigurationPackages
if (registry.containsBeanDefinition(BEAN)) {
//**获取名称为AutoConfigurationPackages的bean定义,实际上注册的class是BasePackages
BeanDefinition beanDefinition = registry.getBeanDefinition(BEAN);
//**获取构造函数的参数值
ConstructorArgumentValues constructorArguments = beanDefinition.getConstructorArgumentValues();
//**把packageNames与原有的包名合并,然后替换原有的构造函数参数值
constructorArguments.addIndexedArgumentValue(0, addBasePackages(constructorArguments, packageNames));
}
//**如果没有注册AutoConfigurationPackages
else {
//**创建bean定义
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
//**class为BasePackages
beanDefinition.setBeanClass(BasePackages.class);
//**设置packageNames为构造函数参数值
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//**注册名称为AutoConfigurationPackages的bean
registry.registerBeanDefinition(BEAN, beanDefinition);
}
}
//**把新的包名与原有的包名合并
private static String[] addBasePackages(ConstructorArgumentValues constructorArguments, String[] packageNames) {
String[] existing = (String[]) constructorArguments.getIndexedArgumentValue(0, String[].class).getValue();
Set<String> merged = new LinkedHashSet<>();
merged.addAll(Arrays.asList(existing));
merged.addAll(Arrays.asList(packageNames));
return StringUtils.toStringArray(merged);
}
//**BasePackages
static final class BasePackages {
private final List<String> packages;
private boolean loggedBasePackageInfo;
//**构造函数
BasePackages(String... names) {
List<String> packages = new ArrayList<>();
for (String name : names) {
if (StringUtils.hasText(name)) {
packages.add(name);
}
}
this.packages = packages;
}
}
3.AutoConfigurationImportSelector
调用
- ConfigurationClassParser.getImports()调用了AutoConfigurationImportSelector内部类AutoConfigurationGroup.process(处理自动配置类),然后调用selectImports(导入自动配置类);
- 调试时没有调用AutoConfigurationImportSelector.selectImports();
- 上述两者功能基本一样,核心功能为getAutoConfigurationEntry(获取导入的自动配置类名,并封装为AutoConfigurationEntry对象);
public Iterable<Group.Entry> getImports() {
for (DeferredImportSelectorHolder deferredImport : this.deferredImports) {
this.group.process(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getImportSelector());
}
return this.group.selectImports();
}
说明(重点)
- 可通过spring.boot.enableautoconfiguration禁用自动配置;
- 默认的自动配置为spring-boot-autoconfigure包META-INF/spring.factories中key=EnableAutoConfiguration的数据。可通过在项目创建resources/META-INF/spring.factories文件,并配置key=EnableAutoConfiguration的数据加载自定义的自动配置类,示例:
//**自定义自动配置,加载Bean Test
public class MyAutoConfiguration {
@Bean
public Test test(){
Test t = new Test();
t.setId("12");
t.setName("pings");
return t;
}
}
//**resources/META-INF/spring.factories配置
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.pings.spring.demo.cache.MyAutoConfiguration
- 上述方法件还可以配置AutoConfigurationImportFilter过滤器和AutoConfigurationImportListener监听器;
- 默认的自动配置依赖关系在spring-boot-autoconfigure包META-INF/spring-autoconfigure-metadata.properties中。同样可通过创建文件添加自定义依赖关系;
- 配置应排除的数据,除了设置@EnableAutoConfiguration的exclude和excludeName,还可以设置spring.autoconfigure.exclude;
- 没有出现在spring.factories中的自动配置,也不能出现在应排除的配置中;
源码
- 实现了BeanClassLoaderAware、ResourceLoaderAware、BeanFactoryAware和EnvironmentAware接口,获取spring上下文中当前的一些运行环境;
- 实现了Ordered接口,指定执行顺序;
- 实现了DeferredImportSelector接口,DeferredImportSelector是延迟的ImportSelector,会在所有的@Configuration之后运行,导入指定的bean;
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
//**标记导入的自动配置为空
private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
//**标记不导入自动配置
private static final String[] NO_IMPORTS = {};
private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
//**设置spring.autoconfigure.exclude,配置应排除的自动配置类名
private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
private ConfigurableListableBeanFactory beanFactory;
private Environment environment;
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
//**过滤器
private ConfigurationClassFilter configurationClassFilter;
//**获取需要导入到spring上下文中的自动配置类名
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
//**没用启用自动配置,则返回NO_IMPORTS,不导入自动配置
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
//**获取导入的自动配置AutoConfigurationEntry对象
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
//**返回AutoConfigurationEntry对象中包含的类名
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
//**排除函数
@Override
public Predicate<String> getExclusionFilter() {
return this::shouldExclude;
}
//**验证是否排除指定的自动配置
private boolean shouldExclude(String configurationClassName) {
return getConfigurationClassFilter().filter(Collections.singletonList(configurationClassName)).isEmpty();
}
//**获取导入的自动配置类名,并封装为AutoConfigurationEntry对象
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
//**没用启用自动配置,则返回EMPTY_ENTRY,导入自动配置为空
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
//**获取@EnableAutoConfiguration的配置的exclude和excludeName
AnnotationAttributes attributes = getAttributes(annotationMetadata);
//**获取spring-boot-autoconfigure包META-INF/spring.factories配置的自动配置类名
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
//**去重
configurations = removeDuplicates(configurations);
//**应排除的类名
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
//**验证不能出现exclusions存在 && configurations不存在的类名
checkExcludedClasses(configurations, exclusions);
//**删除所有应该排除的类名
configurations.removeAll(exclusions);
//**删除过滤器过滤掉的类名(相关依赖条件不满足)
configurations = getConfigurationClassFilter().filter(configurations);
//**触发AutoConfigurationImportEvent事件监听
fireAutoConfigurationImportEvents(configurations, exclusions);
//**把configurations和exclusions封装为AutoConfigurationEntry对象
return new AutoConfigurationEntry(configurations, exclusions);
}
//**获取DeferredImportSelector.Group(导入分组)
@Override
public Class<? extends Group> getImportGroup() {
return AutoConfigurationGroup.class;
}
//**是否启用自动配置
protected boolean isEnabled(AnnotationMetadata metadata) {
//**获取spring.boot.enableautoconfiguration配置,如果不存在/值为true则启用
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
//**如果是AutoConfigurationImportSelector子类的实例,则默认启用
return true;
}
//**获取@EnableAutoConfiguration的配置(exclude和excludeName)
protected AnnotationAttributes getAttributes(AnnotationMetadata metadata) {
String name = getAnnotationClass().getName();
AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
Assert.notNull(attributes, () -> "No auto-configuration attributes ... + "?");
return attributes;
}
//**AutoConfigurationImportSelector处理@EnableAutoConfiguration
protected Class<?> getAnnotationClass() {
return EnableAutoConfiguration.class;
}
//**获取spring-boot-autoconfigure包META-INF/spring.factories中key=EnableAutoConfiguration自动配置类名
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
getBeanClassLoader());
Assert.notEmpty(configurations, "No auto ... in META-INF/spring.factories ...");
return configurations;
}
//**从spring.factories中获取配置的key
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}
//**验证不能出现exclusions存在 && configurations不存在的类名
private void checkExcludedClasses(List<String> configurations, Set<String> exclusions) {
List<String> invalidExcludes = new ArrayList<>(exclusions.size());
for (String exclusion : exclusions) {
if (ClassUtils.isPresent(exclusion, getClass().getClassLoader()) && !configurations.contains(exclusion)) {
invalidExcludes.add(exclusion);
}
}
if (!invalidExcludes.isEmpty()) {
//**存在则抛出异常
handleInvalidExcludes(invalidExcludes);
}
}
//**应排除的类名
protected Set<String> getExclusions(AnnotationMetadata metadata, AnnotationAttributes attributes) {
Set<String> excluded = new LinkedHashSet<>();
//**@EnableAutoConfiguration中exclude应排除的类名
excluded.addAll(asList(attributes, "exclude"));
//**@EnableAutoConfiguration中excludeName应排除的类名
excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
//**配置文件中spring.autoconfigure.exclude应排除的类名
excluded.addAll(getExcludeAutoConfigurationsProperty());
return excluded;
}
//**配置文件中spring.autoconfigure.exclude应排除的类名
private List<String> getExcludeAutoConfigurationsProperty() {
if (getEnvironment() instanceof ConfigurableEnvironment) {
Binder binder = Binder.get(getEnvironment());
return binder.bind(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class).map(Arrays::asList)
.orElse(Collections.emptyList());
}
String[] excludes = getEnvironment().getProperty(PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE, String[].class);
return (excludes != null) ? Arrays.asList(excludes) : Collections.emptyList();
}
//**从spring.factories中获取配置的key=AutoConfigurationImportFilter的类名,并实例化
protected List<AutoConfigurationImportFilter> getAutoConfigurationImportFilters() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationImportFilter.class, this.beanClassLoader);
}
//**获取过滤器
private ConfigurationClassFilter getConfigurationClassFilter() {
//**如果过滤器为空,初始化
if (this.configurationClassFilter == null) {
//**获取spring.factories中配置的过滤器(OnBeanCondition,OnClassCondition,OnWebApplicationCondition)
List<AutoConfigurationImportFilter> filters = getAutoConfigurationImportFilters();
for (AutoConfigurationImportFilter filter : filters) {
//**把所需的spring上下文中运行环境设置到过滤器实例中
invokeAwareMethods(filter);
}
//**封装为ConfigurationClassFilter对象
this.configurationClassFilter = new ConfigurationClassFilter(this.beanClassLoader, filters);
}
//**如果过滤器不为空,表示已经初始化,直接返回
return this.configurationClassFilter;
}
//**字符串去重(LinkedHashSet会保持顺序)
protected final <T> List<T> removeDuplicates(List<T> list) {
return new ArrayList<>(new LinkedHashSet<>(list));
}
//**获取注解配置的属性
protected final List<String> asList(AnnotationAttributes attributes, String name) {
String[] value = attributes.getStringArray(name);
return Arrays.asList(value);
}
//**触发AutoConfigurationImportEvent事件监听
private void fireAutoConfigurationImportEvents(List<String> configurations, Set<String> exclusions) {
//**从spring.factories中获取配置的key=AutoConfigurationImportListener的类名,并实例化
List<AutoConfigurationImportListener> listeners = getAutoConfigurationImportListeners();
if (!listeners.isEmpty()) {
//**创建AutoConfigurationImportEvent事件
AutoConfigurationImportEvent event = new AutoConfigurationImportEvent(this, configurations, exclusions);
//**触发事件监听
for (AutoConfigurationImportListener listener : listeners) {
//**把所需的spring上下文中运行环境设置到监听器实例中
invokeAwareMethods(listener);
listener.onAutoConfigurationImportEvent(event);
}
}
}
//**从spring.factories中获取配置的key=AutoConfigurationImportListener的类名,并实例化
protected List<AutoConfigurationImportListener> getAutoConfigurationImportListeners() {
return SpringFactoriesLoader.loadFactories(AutoConfigurationImportListener.class, this.beanClassLoader);
}
//**把所需的spring上下文中运行环境设置到对应的实例中
private void invokeAwareMethods(Object instance) {
if (instance instanceof Aware) {
if (instance instanceof BeanClassLoaderAware) {
((BeanClassLoaderAware) instance).setBeanClassLoader(this.beanClassLoader);
}
if (instance instanceof BeanFactoryAware) {
((BeanFactoryAware) instance).setBeanFactory(this.beanFactory);
}
if (instance instanceof EnvironmentAware) {
((EnvironmentAware) instance).setEnvironment(this.environment);
}
if (instance instanceof ResourceLoaderAware) {
((ResourceLoaderAware) instance).setResourceLoader(this.resourceLoader);
}
}
}
...Aware接口的getter and setter
//**执行顺序很靠后
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE - 1;
}
//**过滤器
private static class ConfigurationClassFilter {
//**spring-boot-autoconfigure包META-INF/spring-autoconfigure-metadata.properties中每个自动配置类需要的依赖关系
private final AutoConfigurationMetadata autoConfigurationMetadata;
private final List<AutoConfigurationImportFilter> filters;
ConfigurationClassFilter(ClassLoader classLoader, List<AutoConfigurationImportFilter> filters) {
//**获取每个自动配置类需要的依赖关系
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(classLoader);
//**spring.factories中配置的过滤器(OnBeanCondition,OnClassCondition,OnWebApplicationCondition)
this.filters = filters;
}
//**过滤相关依赖条件不满足的自动配置类名
List<String> filter(List<String> configurations) {
long startTime = System.nanoTime();
//**待过滤的自动配置类名数组
String[] candidates = StringUtils.toStringArray(configurations);
//**所有自动配置类都通过的标识(false表示通过)
boolean skipped = false;
//**使用过滤器(OnBeanCondition,OnClassCondition,OnWebApplicationCondition)匹配
for (AutoConfigurationImportFilter filter : this.filters) {
//**匹配所有的自动配置类名
boolean[] match = filter.match(candidates, this.autoConfigurationMetadata);
for (int i = 0; i < match.length; i++) {
if (!match[i]) {
//**不通过,则把当前的类型置为null
candidates[i] = null;
//**不通过,则把skipped置为true
skipped = true;
}
}
}
//**都通过,直接返回configurations
if (!skipped) {
return configurations;
}
//**存在不通过的,则删除后返回
List<String> result = new ArrayList<>(candidates.length);
for (String candidate : candidates) {
if (candidate != null) {
result.add(candidate);
}
}
//**存在不通过的,则打印日志
if (logger.isTraceEnabled()) {
int numberFiltered = configurations.size() - result.size();
logger.trace("Filtered " + numberFiltered + " auto configuration ... ms");
}
return result;
}
}
//**导入分组
private static class AutoConfigurationGroup
implements DeferredImportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {
//**自动配置类名及@EnableAutoConfiguration元数据
private final Map<String, AnnotationMetadata> entries = new LinkedHashMap<>();
//**封装的自动配置Entry
private final List<AutoConfigurationEntry> autoConfigurationEntries = new ArrayList<>();
private ClassLoader beanClassLoader;
private BeanFactory beanFactory;
private ResourceLoader resourceLoader;
//**同ConfigurationClassFilter一样,每个自动配置类需要的依赖关系
private AutoConfigurationMetadata autoConfigurationMetadata;
...Aware接口setter
//**处理导入类信息
@Override
public void process(AnnotationMetadata annotationMetadata, DeferredImportSelector deferredImportSelector) {
//**deferredImportSelector必须是AutoConfigurationImportSelector的实例
Assert.state(deferredImportSelector instanceof AutoConfigurationImportSelector,
() -> String.format("Only %s implementations are ..."));
//**获取导入的自动配置AutoConfigurationEntry对象
AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationImportSelector) deferredImportSelector)
.getAutoConfigurationEntry(annotationMetadata);
//**添加到autoConfigurationEntries中
this.autoConfigurationEntries.add(autoConfigurationEntry);
//**添加到entries中
for (String importClassName : autoConfigurationEntry.getConfigurations()) {
this.entries.putIfAbsent(importClassName, annotationMetadata);
}
}
//**获取导入的类名
@Override
public Iterable<Entry> selectImports() {
//**如果autoConfigurationEntries为空,返回空列表
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
//**所有应排除的类名
Set<String> allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
//**所有应导入的类名
Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
//**删除应排除的类名
processedConfigurations.removeAll(allExclusions);
//**排序后,把@EnableAutoConfiguration元数据和类名封装为Entry对象
return sortAutoConfigurations(processedConfigurations, getAutoConfigurationMetadata()).stream()
.map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
//**获取每个自动配置类需要的依赖关系
private AutoConfigurationMetadata getAutoConfigurationMetadata() {
if (this.autoConfigurationMetadata == null) {
this.autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
}
return this.autoConfigurationMetadata;
}
//**排序,排序规则包括英文字母、Ordered接口和注解(@AutoConfigureBefore @AutoConfigureAfter)
private List<String> sortAutoConfigurations(Set<String> configurations,
AutoConfigurationMetadata autoConfigurationMetadata) {
return new AutoConfigurationSorter(getMetadataReaderFactory(), autoConfigurationMetadata)
.getInPriorityOrder(configurations);
}
//**获取internalCachingMetadataReaderFactory的实例
private MetadataReaderFactory getMetadataReaderFactory() {
try {
return this.beanFactory.getBean(SharedMetadataReaderFactoryContextInitializer.BEAN_NAME,
MetadataReaderFactory.class);
}
catch (NoSuchBeanDefinitionException ex) {
return new CachingMetadataReaderFactory(this.resourceLoader);
}
}
}
//**封装的自动配置Entry
protected static class AutoConfigurationEntry {
//**自动配置类名
private final List<String> configurations;
//**排除的类名
private final Set<String> exclusions;
...构造方法、getter and setter
}
}