springboot自动装配原理简单解析

@SpringBootApplication
public class Demo2020Application {

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

}

首先我们看看@SpringBootApplication这个注解,点进去

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
// 自动扫描符合条件的Bean到容器中,这个注解会默认扫描声明类所在的包下面所有的包
@ComponentScan(excludeFilters = { 
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
	    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

}

再来看一下

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {

	@AliasFor("basePackages")
	String[] value() default {};
//指定多个包扫描
	@AliasFor("value")
	String[] basePackages() default {};
//对指定的类和接口所属的包扫描
	Class<?>[] basePackageClasses() default {};
//未扫描到的bean自动命名
	Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;

	Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
//指定代理是否被扫描
	ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;

	String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
//是否开启对@Component@Repository@Service@Controller的类进行检测
	boolean useDefaultFilters() default true;
//指定扫描的过滤器
	Filter[] includeFilters() default {};
//指定不扫描的过滤器
	Filter[] excludeFilters() default {};
// 是否对注册扫描的bean设置懒加载
	boolean lazyInit() default false;

	@Retention(RetentionPolicy.RUNTIME)
	@Target({})
	@interface Filter {

		FilterType type() default FilterType.ANNOTATION;

		@AliasFor("classes")
		Class<?>[] value() default {};

		@AliasFor("value")
		Class<?>[] classes() default {};

		String[] pattern() default {};

	}

}

下面我们看看@SpringBootConfiguration

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
    @AliasFor(
        annotation = Configuration.class
    )
    boolean proxyBeanMethods() default true;
}

只是对@Configuration注解的一个封装

下面就是@EnableAutoConfiguration这个注解,重点,自动装配的原理就在这

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

	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	Class<?>[] exclude() default {};

	String[] excludeName() default {};

}

利用@Import注解,将所有符合自动装配条件的bean注入到IOC容器中,进入AutoConfigurationImportSelector中

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
	//判断是不是禁用了自动配置
    if (!isEnabled(annotationMetadata)) {
		return NO_IMPORTS;
	}
// 如果没有禁用
	AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
	return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
protected boolean isEnabled(AnnotationMetadata metadata) {
	if (getClass() == AutoConfigurationImportSelector.class) {
		return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
	}
	return true;
}

protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
	if (!isEnabled(annotationMetadata)) {
		return EMPTY_ENTRY;
	}
//加载所有的预先定义的配置信息
//这些配置信息在org.springframework.boot.autoconfigure包下的META-INF/spring-autoconfigure-metadata.properties文件中
	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 = getConfigurationClassFilter().filter(configurations);
//发布自动装配完成事件
	fireAutoConfigurationImportEvents(configurations, exclusions);
	return new AutoConfigurationEntry(configurations, exclusions);
}

上面还有一个文件spring.factories

这个文件基本上springboot的包都存在,而且所有的spring.factories都会加载

所以就可以在我们的项目的META-INF文件夹下建立一个spring.factories,写上我们自己的配置,然后项目启动的时候也会加载,这就是自义定starter

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值