SpringBoot源码学习系列——自动配置原理(一)

核心原理概述

关键点

  • @EnableAutoConfiguration 开启自动配置
  • spring.factories 提供自动配置类的全路径,位于jar包META-INF目录下
  • @Conditional 条件注解,自动配置类实例化的前置条件
  • Starters 配置及依赖支持
  • XXAutoConfiguration 具体的自动配置类

关系图

扫描加载
指定自动配置类全路径
提供前置条件判断
配置及依赖支持
EnableAutoConfiguration注解
spring.factories
XXAutoConfiguration
Conditional条件注解
Starters

自动配置流程

通过@SpringBootApplication引入的@EnableAutoConfiguration开启自动配置,去加载spring.factories文件中的AutoConfiguration类,当XXAutoConfiguration满足条件注解@Conditional的前置条件时,实例化XXAutoConfiguration中定义的Bean,并注入Spring容器,完成依赖的自动配置。

@SpringBootApplication注解

注解结构

自动装配
包扫描
提供注入bean的能力
Import注解
AutoConfigurationPackage注解
EnableAutoConfiguration注解
SpringBootApplication注解
ComponentScan注解
Component注解
Configuration注解
SpringBootConfiguration注解

源码解读

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
		@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * 排除指定的自动配置类(不想走SpringBoot的自动配置来初始化的bean),覆盖了EnableAutoConfiguration注解的exclude属性
	 * @return the classes to exclude
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * 根据类名排除指定的自动配置类,覆盖了EnableAutoConfiguration注解的excludeName属性
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	@AliasFor(annotation = EnableAutoConfiguration.class)
	String[] excludeName() default {};

	/**
	 * Base packages to scan for annotated components. Use scanBasePackageClasses
	 * for a type-safe alternative to String-based package names.
	 * 指定扫描的package,开启此package下直接或间接使用了@Component注解的类的初始化,作为ComponentScan注解basePackages属性的别名
	 * @return base packages to scan
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
	String[] scanBasePackages() default {};

	/**
	 * Type-safe alternative to scanBasePackages for specifying the packages to
	 * scan for annotated components. The package of each class specified will be scanned.
	 * 根据类名指定扫描的包,指定类的包都会被扫描以初始化,类型安全
	 * @return base packages to scan
	 * @since 1.3.0
	 */
	@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
	Class<?>[] scanBasePackageClasses() default {};

	/**
	 * Specify whether @Bean methods should get proxied in order to enforce
	 * bean lifecycle behavior, e.g. to return shared singleton bean instances even in
	 * case of direct {@code @Bean} method calls in user code. This feature requires
	 * method interception, implemented through a runtime-generated CGLIB subclass which
	 * comes with limitations such as the configuration class and its methods not being
	 * allowed to declare {@code final}.
	 * 指定是否代理@Bean方法来初始化bean,需要运行时生成CGLIB子类进行拦截(CGLIB方式代理的类及其方法不能是final)
	 * @since 2.2
	 * @return whether to proxy {@code @Bean} methods
	 */
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}

@EnableAutoConfiguration注解

被@EnableAutoConfiguration注解的类所在package会被作为扫描的根路径,因此被@SpringBootApplication注解的类位于顶级package下,以保证所有类可被扫描到。由此可见,入口函数或main方法不依赖于@SpringBootApplication注解,@SpringBootApplication也可以放在其他类上,但该类必须是在顶级package下。

@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
	// 提供常量,用于配置自动配置的开启、关闭
	String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

	/**
	 * Exclude specific auto-configuration classes such that they will never be applied.
	 * @return the classes to exclude
	 */
	Class<?>[] exclude() default {};

	/**
	 * Exclude specific auto-configuration class names such that they will never be
	 * applied.
	 * @return the class names to exclude
	 * @since 1.3.0
	 */
	String[] excludeName() default {};

}

你可能感兴趣的:(spring,boot,学习,spring,Java)