栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

springboot源码自动装配-AutoConfigurationImportSelector

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

springboot源码自动装配-AutoConfigurationImportSelector


package org.springframework.boot.autoconfigure;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.linkedHashMap;
import java.util.linkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.Aware;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DeferredimportSelector;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.SpringFactoriesLoader;
import org.springframework.core.type.Annotationmetadata;
import org.springframework.core.type.classreading.CachingmetadataReaderFactory;
import org.springframework.core.type.classreading.metadataReaderFactory;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;


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

	private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

	private ConfigurableListableBeanFactory beanFactory;

	private Environment environment;

	private ClassLoader beanClassLoader;

	private ResourceLoader resourceLoader;

	@Override
	public String[] selectimports(Annotationmetadata annotationmetadata) {
		//是否启用自动配置
		if (!isEnabled(annotationmetadata)) {
			return NO_importS;
		}
		//获取meta-INF/spring-autoconfigure-metadata.properties文件的配置,返回AutoConfigurationmetadata类
		AutoConfigurationmetadata autoConfigurationmetadata = AutoConfigurationmetadataLoader
				.loadmetadata(this.beanClassLoader);
		//获取自动配置类,返回AutoConfigurationEntry
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationmetadata,
				annotationmetadata);
		//返回要自动配置的类名
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

	
	protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationmetadata autoConfigurationmetadata,
															   Annotationmetadata annotationmetadata) {
		if (!isEnabled(annotationmetadata)) {
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationmetadata);
		//meta-INF/spring.factories下获取路径是org.springframework.boot.autoconfigure.EnableAutoConfiguration的配置
		List configurations = getCandidateConfigurations(annotationmetadata, attributes);
		//去重,并可以由子类拓展
		configurations = removeDuplicates(configurations);
		//获取排除的自动配置
		Set exclusions = getExclusions(annotationmetadata, attributes);
		//校验配置信息是否可加载,并且不能排除自动配置信息
		checkExcludedClasses(configurations, exclusions);
		//从自动配置移除忽略的
		configurations.removeAll(exclusions);
		//通过meta-INF/spring.factories下AutoConfigurationimportFilter来过滤不需要的bean.
		//也就是通过OnBeanCondition,OnClassCondition,OnWebApplicationCondition来过滤不需要的bean.
		configurations = filter(configurations, autoConfigurationmetadata);
		//执行自动装配加载的监听器
		fireAutoConfigurationimportEvents(configurations, exclusions);
		//封装到AutoConfigurationEntry并返回
		return new AutoConfigurationEntry(configurations, exclusions);
	}

	@Override
	public Class getimportGroup() {
		return AutoConfigurationGroup.class;
	}

	protected boolean isEnabled(Annotationmetadata metadata) {
		//如果是当前类是AutoConfigurationimportSelector
		if (getClass() == AutoConfigurationimportSelector.class) {
			//从当前环境中获取spring.boot.enableautoconfiguration是否启用自动配置,默认为true
			return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
		}
		return true;
	}

	
	protected AnnotationAttributes getAttributes(Annotationmetadata metadata) {
		String name = getAnnotationClass().getName();
		AnnotationAttributes attributes = AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(name, true));
		Assert.notNull(attributes, () -> "No auto-configuration attributes found. Is " + metadata.getClassName()
				+ " annotated with " + ClassUtils.getShortName(name) + "?");
		return attributes;
	}

	
	protected Class getAnnotationClass() {
		return EnableAutoConfiguration.class;
	}

	
	protected List getCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) {
		List configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());
		Assert.notEmpty(configurations, "No auto configuration classes found in meta-INF/spring.factories. If you "
				+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}

	
	protected Class getSpringFactoriesLoaderFactoryClass() {
		return EnableAutoConfiguration.class;
	}

	private void checkExcludedClasses(List configurations, Set exclusions) {
		List 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 void handleInvalidExcludes(List invalidExcludes) {
		StringBuilder message = new StringBuilder();
		for (String exclude : invalidExcludes) {
			message.append("t- ").append(exclude).append(String.format("%n"));
		}
		throw new IllegalStateException(String.format(
				"The following classes could not be excluded because they are not auto-configuration classes:%n%s",
				message));
	}

	
	protected Set getExclusions(Annotationmetadata metadata, AnnotationAttributes attributes) {
		Set excluded = new linkedHashSet<>();
		excluded.addAll(asList(attributes, "exclude"));
		excluded.addAll(Arrays.asList(attributes.getStringArray("excludeName")));
		excluded.addAll(getExcludeAutoConfigurationsProperty());
		return excluded;
	}

	private List 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();
	}

	private List filter(List configurations, AutoConfigurationmetadata autoConfigurationmetadata) {
		long startTime = System.nanoTime();
		String[] candidates = StringUtils.toStringArray(configurations);
		boolean[] skip = new boolean[candidates.length];
		boolean skipped = false;
		for (AutoConfigurationimportFilter filter : getAutoConfigurationimportFilters()) {
			invokeAwareMethods(filter);
			boolean[] match = filter.match(candidates, autoConfigurationmetadata);
			for (int i = 0; i < match.length; i++) {
				if (!match[i]) {
					skip[i] = true;
					candidates[i] = null;
					skipped = true;
				}
			}
		}
		if (!skipped) {
			return configurations;
		}
		List result = new ArrayList<>(candidates.length);
		for (int i = 0; i < candidates.length; i++) {
			if (!skip[i]) {
				result.add(candidates[i]);
			}
		}
		if (logger.isTraceEnabled()) {
			int numberFiltered = configurations.size() - result.size();
			logger.trace("Filtered " + numberFiltered + " auto configuration class in "
					+ TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime) + " ms");
		}
		return new ArrayList<>(result);
	}

	protected List getAutoConfigurationimportFilters() {
		return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader);
	}

	protected final  List removeDuplicates(List list) {
		return new ArrayList<>(new linkedHashSet<>(list));
	}

	protected final List asList(AnnotationAttributes attributes, String name) {
		String[] value = attributes.getStringArray(name);
		return Arrays.asList((value != null) ? value : new String[0]);
	}

	private void fireAutoConfigurationimportEvents(List configurations, Set exclusions) {
		//获取到自动配置的监听器
		List listeners = getAutoConfigurationimportListeners();
		if (!listeners.isEmpty()) {
			AutoConfigurationimportEvent event = new AutoConfigurationimportEvent(this, configurations, exclusions);
			for (AutoConfigurationimportListener listener : listeners) {
				//设置Aware
				invokeAwareMethods(listener);
				//执行监听器
				listener.onAutoConfigurationimportEvent(event);
			}
		}
	}

	protected List getAutoConfigurationimportListeners() {
		return SpringFactoriesLoader.loadFactories(AutoConfigurationimportListener.class, this.beanClassLoader);
	}

	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);
			}
		}
	}

	@Override
	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		Assert.isInstanceOf(ConfigurableListableBeanFactory.class, beanFactory);
		this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
	}

	protected final ConfigurableListableBeanFactory getBeanFactory() {
		return this.beanFactory;
	}

	@Override
	public void setBeanClassLoader(ClassLoader classLoader) {
		this.beanClassLoader = classLoader;
	}

	protected ClassLoader getBeanClassLoader() {
		return this.beanClassLoader;
	}

	@Override
	public void setEnvironment(Environment environment) {
		this.environment = environment;
	}

	protected final Environment getEnvironment() {
		return this.environment;
	}

	@Override
	public void setResourceLoader(ResourceLoader resourceLoader) {
		this.resourceLoader = resourceLoader;
	}

	protected final ResourceLoader getResourceLoader() {
		return this.resourceLoader;
	}

	@Override
	public int getOrder() {
		return Ordered.LOWEST_PRECEDENCE - 1;
	}

	private static class AutoConfigurationGroup
			implements DeferredimportSelector.Group, BeanClassLoaderAware, BeanFactoryAware, ResourceLoaderAware {

		private final Map entries = new linkedHashMap<>();

		private final List autoConfigurationEntries = new ArrayList<>();

		private ClassLoader beanClassLoader;

		private BeanFactory beanFactory;

		private ResourceLoader resourceLoader;

		private AutoConfigurationmetadata autoConfigurationmetadata;

		@Override
		public void setBeanClassLoader(ClassLoader classLoader) {
			this.beanClassLoader = classLoader;
		}

		@Override
		public void setBeanFactory(BeanFactory beanFactory) {
			this.beanFactory = beanFactory;
		}

		@Override
		public void setResourceLoader(ResourceLoader resourceLoader) {
			this.resourceLoader = resourceLoader;
		}

		@Override
		public void process(Annotationmetadata annotationmetadata, DeferredimportSelector deferredimportSelector) {
			Assert.state(deferredimportSelector instanceof AutoConfigurationimportSelector,
					() -> String.format("only %s implementations are supported, got %s",
							AutoConfigurationimportSelector.class.getSimpleName(),
							deferredimportSelector.getClass().getName()));
			//获取自动装配的配置
			AutoConfigurationEntry autoConfigurationEntry = ((AutoConfigurationimportSelector) deferredimportSelector)
					.getAutoConfigurationEntry(getAutoConfigurationmetadata(), annotationmetadata);
			this.autoConfigurationEntries.add(autoConfigurationEntry);
			for (String importClassName : autoConfigurationEntry.getConfigurations()) {
				this.entries.putIfAbsent(importClassName, annotationmetadata);
			}
		}

		@Override
		public Iterable selectimports() {
			if (this.autoConfigurationEntries.isEmpty()) {
				return Collections.emptyList();
			}
			//获取要排除的
			Set allExclusions = this.autoConfigurationEntries.stream()
					.map(AutoConfigurationEntry::getExclusions).flatMap(Collection::stream).collect(Collectors.toSet());
			//获取到自动当前自动装配的属性
			Set processedConfigurations = this.autoConfigurationEntries.stream()
					.map(AutoConfigurationEntry::getConfigurations).flatMap(Collection::stream)
					.collect(Collectors.toCollection(linkedHashSet::new));
			processedConfigurations.removeAll(allExclusions);
			//排序
			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;
		}

		private List sortAutoConfigurations(Set configurations,
													AutoConfigurationmetadata autoConfigurationmetadata) {
			return new AutoConfigurationSorter(getmetadataReaderFactory(), autoConfigurationmetadata)
					.getInPriorityOrder(configurations);
		}

		private metadataReaderFactory getmetadataReaderFactory() {
			try {
				return this.beanFactory.getBean(SharedmetadataReaderFactoryContextInitializer.BEAN_NAME,
						metadataReaderFactory.class);
			} catch (NoSuchBeanDefinitionException ex) {
				return new CachingmetadataReaderFactory(this.resourceLoader);
			}
		}

	}

	protected static class AutoConfigurationEntry {

		private final List configurations;

		private final Set exclusions;

		private AutoConfigurationEntry() {
			this.configurations = Collections.emptyList();
			this.exclusions = Collections.emptySet();
		}

		
		AutoConfigurationEntry(Collection configurations, Collection exclusions) {
			this.configurations = new ArrayList<>(configurations);
			this.exclusions = new HashSet<>(exclusions);
		}

		public List getConfigurations() {
			return this.configurations;
		}

		public Set getExclusions() {
			return this.exclusions;
		}

	}

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/288082.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号