springboot 最新版自动装配

spring boot 自动装配 自己小结

                            @SpringBootApplication
									||
                                    ||点击进来发现
                                    ||
                                    \/
                              @Target(ElementType.TYPE)
                            @Retention(RetentionPolicy.RUNTIME)
                            @Documented
                            @Inherited
                            @SpringBootConfiguration //说明这是一个自动配置类
                            @EnableAutoConfiguration//自动配置类
                            @ComponentScan(excludeFilters = {
    
     @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
                                    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) }) 
                                    ||
                                    ||点击进来发现
                                    ||
                                    \/     
                          @Target(ElementType.TYPE)
                          @Retention(RetentionPolicy.RUNTIME)
                          @Documented
                          @Inherited
                          @AutoConfigurationPackage  //自动配置包
                          @Import(AutoConfigurationImportSelector.class)  //自动配置导入选择器            					   ||
                                    ||点击进来发现
                                    ||
                                    \/  	                                       
//导入这个类
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;
		}
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
				annotationMetadata);  //获取自动配置条目,进入这个方法
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

进入getAutoConfigurationEntry () 方法

/**
	 * Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
	 * of the importing {@link Configuration @Configuration} class.
	 * @param autoConfigurationMetadata the auto-configuration metadata
	 * @param annotationMetadata the annotation metadata of the configuration class
	 * @return the auto-configurations that should be imported
	 */
	protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
    
    
		if (!isEnabled(annotationMetadata)) {
    
    
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
		List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);//获取候选配置 
		configurations = removeDuplicates(configurations);//是否有重复的
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);//排除不用的自动配置类
		checkExcludedClasses(configurations, exclusions);
		configurations.removeAll(exclusions);//排除
		configurations = filter(configurations, autoConfigurationMetadata); //判断有没有导入jar包
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

点击进入 getCandidateConfigurations () 候选配置方法

/**
	 * Return the auto-configuration class names that should be considered. By default
	 * this method will load candidates using {@link SpringFactoriesLoader} with
	 * {@link #getSpringFactoriesLoaderFactoryClass()}.
	 * @param metadata the source metadata
	 * @param attributes the {@link #getAttributes(AnnotationMetadata) annotation
	 * attributes}
	 * @return a list of candidate configurations
	 */
	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    
    
		List<String> configurations =
 //加载工厂名称 loadFactoryNames
           SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
				getBeanClassLoader());//传入2个参数 一个加载自动装配类 ,还有类加载器 
		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;
	}

点击进入 loadFactoryNames() 会加载配置的 META-INF/spring.factories 中的自动装配类

private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    
    
		MultiValueMap<String, String> result = cache.get(classLoader);//第一次查询将全部全部放到缓存中    MultiValueMap 结构 key 多个value  
		if (result != null) {
    
    
			return result;
		}

		try {
    
    
			Enumeration<URL> urls = (classLoader != null ?
					classLoader.getResources(FACTORIES_RESOURCE_LOCATION) :
					ClassLoader.getSystemResources(FACTORIES_RESOURCE_LOCATION));
			result = new LinkedMultiValueMap<>();
			while (urls.hasMoreElements()) {
    
    
				URL url = urls.nextElement();
				UrlResource resource = new UrlResource(url);
				Properties properties = PropertiesLoaderUtils.loadProperties(resource);
				for (Map.Entry<?, ?> entry : properties.entrySet()) {
    
    
					String factoryTypeName = ((String) entry.getKey()).trim();
					for (String factoryImplementationName : StringUtils.commaDelimitedListToStringArray((String) entry.getValue())) {
    
    
						result.add(factoryTypeName, factoryImplementationName.trim());
					}
				}
			}
			cache.put(classLoader, result);
			return result;
		}
		catch (IOException ex) {
    
    
			throw new IllegalArgumentException("Unable to load factories from location [" +
					FACTORIES_RESOURCE_LOCATION + "]", ex);
		}
	}
//返回spi 方式

猜你喜欢

转载自blog.csdn.net/weng74/article/details/107709182