自动装配原理及源码解析
自动装配实现流程图简述自动装配步骤详解
核心代码加载SpringBoot可以自动装配集合利用linkedHashSet对得到的需要自动装配的集合去重过滤@SpringBootApplication注解中exclude参数集合利用AutoConfigurationimportFilter过滤器对不满足条件的配置类,进行过滤
OnClassConditionOnWebApplicationConditionOnBeanCondition源码解析 按照优先级,对配置类进行实例化(bean初始化)
自动装配原理及源码解析 自动装配实现流程图简述 自动装配步骤详解 核心代码 @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);
}
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationmetadata autoConfigurationmetadata,
Annotationmetadata annotationmetadata) {
if (!isEnabled(annotationmetadata)) {
return EMPTY_ENTRY;
}
//通过加载项目中所有jar包中meta-INF/spring.factories获取可自动装配的类全路径集合
AnnotationAttributes attributes = getAttributes(annotationmetadata);
List configurations = getCandidateConfigurations(annotationmetadata, attributes);
//利用linkedHashSet对得到的需要自动装配的集合去重
configurations = removeDuplicates(configurations);
Set exclusions = getExclusions(annotationmetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationmetadata);
//触发自动装配相关的监听事件
fireAutoConfigurationimportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
加载SpringBoot可以自动装配集合
protected ListgetCandidateConfigurations(Annotationmetadata metadata, AnnotationAttributes attributes) { //通过加载项目中所有jar包中meta-INF/spring.factories获取可自动装配的类全路径集合 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; }
SpringFactoriesLoader.loadFactoryNames方法
public static ListloadFactoryNames(Class> factoryType, @Nullable ClassLoader classLoader) { String factoryTypeName = factoryType.getName(); return (List)loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); }
加载所有包含meta-INF/spring.factories的jar包中需要自动装配的类,并存放到map集合当中
private static Map利用linkedHashSet对得到的需要自动装配的集合去重> loadSpringFactories(@Nullable ClassLoader classLoader) { MultiValueMap result = (MultiValueMap)cache.get(classLoader); if (result != null) { return result; } else { try { Enumeration urls = classLoader != null ? classLoader.getResources("meta-INF/spring.factories") : ClassLoader.getSystemResources("meta-INF/spring.factories"); linkedMultiValueMap result = new linkedMultiValueMap(); while(urls.hasMoreElements()) { URL url = (URL)urls.nextElement(); UrlResource resource = new UrlResource(url); Properties properties = PropertiesLoaderUtils.loadProperties(resource); Iterator var6 = properties.entrySet().iterator(); while(var6.hasNext()) { Entry, ?> entry = (Entry)var6.next(); String factoryTypeName = ((String)entry.getKey()).trim(); String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue()); int var10 = var9.length; for(int var11 = 0; var11 < var10; ++var11) { String factoryImplementationName = var9[var11]; result.add(factoryTypeName, factoryImplementationName.trim()); } } } cache.put(classLoader, result); return result; } catch (IOException var13) { throw new IllegalArgumentException("Unable to load factories from location [meta-INF/spring.factories]", var13); } } }
protected final过滤@SpringBootApplication注解中exclude参数集合List removeDuplicates(List list) { return new ArrayList<>(new linkedHashSet<>(list)); }
核心方法:
protected Set利用AutoConfigurationimportFilter过滤器对不满足条件的配置类,进行过滤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; }
先来看下会用的的过滤器,入下图所示
下面我们每个类简单说明一些
源码分析
重点分析
See Also: ConditionalOnClass, ConditionalOnMissingClass
@ConditionalOnClass :某个class位于类路径上,才会实例化一个Bean
@ConditionalOnMissingClass: 某个class类路径上不存在的时候,才会实例化一个Bean
简单描述:就是根据需要自动装配类上以上两个注解中条件满足与否过滤掉不需要加载的自动装配类
同上重点分析
See Also:ConditionalOnWebApplication, ConditionalOnNotWebApplication
@ConditionalOnWebApplication: 当前项目是Web项目的条件下,才会实例化一个Bean
@ConditionalOnNotWebApplication: 当项目不是web项目的条件下,才会实例化一个Bean
同上重点分析
See Also:ConditionalOnBean, ConditionalOnMissingBean, ConditionalOnSingleCandidate
@ConditionalOnBean:当容器里有指定Bean的条件下,才会实例化一个Bean
@ConditionalOnMissingBean:当容器里没有指定Bean的情况下,才会实例化一个Bean
@ConditionalOnSingleCandidate:当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean,才会实例化一个Bean
private Listfilter(List configurations, AutoConfigurationmetadata autoConfigurationmetadata) { long startTime = System.nanoTime(); String[] candidates = StringUtils.toStringArray(configurations); boolean[] skip = new boolean[candidates.length]; boolean skipped = false; //final List autoConfigurationimportFilters = getAutoConfigurationimportFilters(); //获取过滤器集合,过滤得到满足条件的集合 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); }
获取过滤器集合的方法
//主要获取到OnClassCondition,OnWebApplicationCondition,OnBeanCondition三个过滤器 protected List按照优先级,对配置类进行实例化(bean初始化)getAutoConfigurationimportFilters() { return SpringFactoriesLoader.loadFactories(AutoConfigurationimportFilter.class, this.beanClassLoader); }
@Override public Iterableselectimports() { 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); //对配置类进行按照顺序进行Bean实例化 return sortAutoConfigurations(processedConfigurations, getAutoConfigurationmetadata()).stream() .map((importClassName) -> new Entry(this.entries.get(importClassName), importClassName)) .collect(Collectors.toList()); }
//获取实例化集合 private ListsortAutoConfigurations(Set configurations, AutoConfigurationmetadata autoConfigurationmetadata) { return new AutoConfigurationSorter(getmetadataReaderFactory(), autoConfigurationmetadata) .getInPriorityOrder(configurations); } //实例化Bean private metadataReaderFactory getmetadataReaderFactory() { try { return this.beanFactory.getBean(SharedmetadataReaderFactoryContextInitializer.BEAN_NAME, metadataReaderFactory.class); } catch (NoSuchBeanDefinitionException ex) { return new CachingmetadataReaderFactory(this.resourceLoader); } }



