SpringBoot 自动装配源码剖析

启动类注解

@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) })
public @interface SpringBootApplication {
 ...
}
复制代码

1. @SpringBootConfiguration

SpringBootConfiguration相当于对@Configuration做了一层包装,等同于@Configuration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {

}
复制代码

2. @EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

}
复制代码

2.1 @AutoConfigurationPackage

通过@Import 引入AutoConfigurationPackages.Registar类, 会对@SpringBootApplication标注的类的包及其子包进行扫描,将组件添加到容器内

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {

}
-----------------------------------------------------------------------------------------
static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
		//默认会扫描@SpringBootApplication标注的类所在的包和子包下所有组件
		register(registry, new PackageImport(metadata).getPackageName());
	}

	@Override
	public Set<Object> determineImports(AnnotationMetadata metadata) {
		return Collections.singleton(new PackageImport(metadata));
	}

}
复制代码

2.2 @Import(AutoConfigurationImportSelector.class)

帮助SpringBoot应用将所有符合条件的@Configuration配置加载到当前SpringBoot创建并使用的IOC容器中

org.springframework.boot.autoconfigure.AutoConfigurationImportSelector#selectImports

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	//判断 @EnableAutoConfiguration注解有没有开启,默认开启
	if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
	//1.加载配置文件META-INF/spring-autoconfigure-metadata.properties 从中获取所有支出自动配置的条件,
	//自动配置的类全名.条件=值
	AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
			.loadMetadata(this.beanClassLoader);
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata,
			annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

复制代码

2.3 @ComponentScan

@ComponentScan注解扫描SpringBoot主程序启动类所在的包及子包,路径通过上面的@AutoConfigurationPackage注解解析获取

总结

@SpringBootApplication注解

|- @SpringBootApplication  //核心注解
	|- @SpringBootConfiguration //标志为配置注解
		|- @Configuration	//标志为配置注解
	|- @AutoConfigurationPackage //自动配置包,获取到启动类(标注@SpringBootApplication注解)所在包路径
	|- @Import(AutoConfigurationImportSelector.class) //加载META-INF/spring.factories中定义的bean到IOC容器中
|- @ComponentScan //包扫描
复制代码

3.自定义Starter

3.1 引入依赖

	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-autoconfigure</artifactId>
		<version>2.1.6.RELEASE</version>
	</dependency>
复制代码

3.2 编写注入类

@Configuration
@ConditionalOnClass(SimpleBean.class)
public class MyAutoConfiguration {

    static {
        System.out.println("My Auto Configuration Init.....");
    }

    @Bean
    public SimpleBean simpleBean(){
        return new SimpleBean();
    }
}
-----------
@EnableConfigurationProperties(SimpleBean.class)
@ConfigurationProperties(prefix = "simplebean")
public class SimpleBean {
    private int id;
    private String name;

    @Override
    public String toString() {
        return "SimpleBean{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
----------------

@Configuration
@ConditionalOnClass(SimpleBean.class)
public class MyAutoConfiguration {

    static {
        System.out.println("My Auto Configuration Init.....");
    }

    @Bean
    public SimpleBean simpleBean(){
        return new SimpleBean();
    }
}

复制代码

3.3 编写resources/META-INF/spring.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  com.lagou.config.MyAutoConfiguration
复制代码

3.4 调用方引入使用方法

simplebean:
  id: 1
  name: 自定义starter
复制代码
@RestController
public class DemoController {

    @Autowired
    private SimpleBean simpleBean;

    @RequestMapping("/")
    public SimpleBean hello(){
        return simpleBean;
    }
}
复制代码

猜你喜欢

转载自juejin.im/post/7077813130985750559