SpringBoot 自动装配

  作者:记性不好的阁主



1、springboot启动类:


package com.sourcecode.helloworld;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloworldApplication {

public static void main(String[] args) {
SpringApplication.run(HelloworldApplication.class, args);
}

}


@SpringBootApplication   注解标志了这是一个springboot应用


2、SpringBootApplication注解源码




该注解又包含了两个配置注解:


@SpringBootConfiguration   注解标志了springboot配置

@EnableAutoConfiguration   注解标志了启动springboot自动配置


  • 2-1、SpringBootConfiguration注解源码




该注解又包含了一个配置注解:


@Configuration   注解标志了这是一个配置


  • 2-1-1、Configuration注解源码:




@Component   注解标志了这个注解可被spring扫描到


  • 2-2、EnableAutoConfiguration注解源码




该注解又包含了两个注解:


@AutoConfigurationPackage  注解标志自动配置包

@Import(AutoConfigurationImportSelector.class)   注解导入自动配置选择器


  • 2-2-1、AutoConfigurationPackage注解源码




该注解又包含了一个注解:


@Import(AutoConfigurationPackages.Registrar.class)   注解导入自动配置包注册器


  • 2-2-1-1、Registrar类源码




  • 2-2-2、AutoConfigurationImportSelector类源码:




核心方法:



/**
* 返回应考虑的自动配置类名。默认情况下 * 这个方法将使用{@link SpringFactoriesLoader}加载候选对象 * {@link # getSpringFactoriesLoaderFactoryClass()}。 * @param metadata源元数据 * @param attributes {@link #getAttributes(AnnotationMetadata)注释 * 属性} * 返回候选配置的列表
*/
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> 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;
}


  • getSpringFactoriesLoaderFactoryClass()方法内容:


/**
*返回{@link SpringFactoriesLoader}用于加载配置的类 *候选人。 *返回工厂类
*/
protected Class<?> getSpringFactoriesLoaderFactoryClass() {
return EnableAutoConfiguration.class;
}


这意味着标注了这个类的都将在启动的时候被加载


回过头来看SpringBootApplication注解源码,就标注了这个注解启动时就会被加载:




  • SpringFactoriesLoader.loadFactoryNames()方法内容:


/**
类的工厂实现的完全限定类名 {@value #FACTORIES_RESOURCE_LOCATION},使用给定类型 *类装入器。 * 从Spring Framework 5.3开始,如果一个特定的实现类名 对于给定的工厂类型,会多次发现重复的工厂类型 *被忽略。 表示工厂的接口或抽象类 用于加载资源的类加载器;可以 * {@code null}使用默认值 * @throws IllegalArgumentException,如果在加载工厂名称时发生错误 * @see # loadFactories
*/
public static List<String> loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) {
ClassLoader classLoaderToUse = classLoader
;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.
class.getClassLoader();
}
String factoryTypeName = factoryType.getName()
;
return loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
}


String factoryTypeName = factoryType.getName(); 获取工厂类型名


  • loadSpringFactories(ClassLoader classLoader) 方法内容:



其中FACTORIES_RESOURCE_LOCATION 为 META-INF/spring.factories 文件


/**
* The location to look for factories.
* <p>Can be present in multiple JAR files.
*/
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";


META-INF/spring.factories内容:




存放着所有的自动配置类,全部都加载到上面loadSpringFactories(ClassLoader classLoader) 方法中的properties配置类中,但并不一定会生效,必须满足自动配置类的生效条件


如mvc自动配置类:






满足这些条件才会生效!



相关推荐

评论 抢沙发

表情

分类选择