1.概述
我们今天可以来分析一下Spring Boot
自动配置的实现原理和自己手动封装一个starter了。
我们一直在强调Spring Boot
能成为当下主流首选开发框架的主要原因在于其核心思想:约定大于配置,自动配置,条件装配。基于这些特性使得Spring Boot
集成其他框架非常简单快捷。
使用Spring Boot
创建的项目启动、执行也非常简单,只需要执行启动类的main()方法即可,不需要做其他操作,Spring Boot
会自动装配相关所需依赖和配置。
@SpringBootApplication
public class CommonDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CommonDemoApplication.class, args);
}
}
复制代码
2.Spring Boot自动配置原理
从上面项目启动类可以看出,没有什么复杂的启动逻辑,就只使用一个注解@SpringBootApplication
,这就是Spring Boot
自动配置的核心入口所在,其定义如下:
@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 {
// 排除掉自动配置的class
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
// 排除掉自动配置的全路径类名
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
// 配置扫描的包路径
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
// 配置扫描的类
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
// beanName生成器
@AliasFor(annotation = ComponentScan.class, attribute = "nameGenerator")
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
// 配置类代理模式:proxyBeanMethods:代理bean的方法
// Full(proxyBeanMethods = true)、【保证每个@Bean方法被调用多少次返回的组件都是单实例的】
// Lite(proxyBeanMethods = false)【每个@Bean方法被调用多少次返回的组件都是新创建的】
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
复制代码
从定义可知@SpringBootApplication
是一个复合注解,所以接下来我们逐一看看其关联使用的注解。
2.1 @SpringBootConfiguration
@SpringBootConfiguration
的定义如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
@AliasFor(annotation = Configuration.class)
boolean proxyBeanMethods() default true;
}
复制代码
从定义可知,该注解就是一个配置类注解,其作用和属性和@Configuration
注解一样,只是这里语义化罢了,就像@Controller
和@Component
一个道理。
2.2 @EnableAutoConfiguration
从名字上看,@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 {};
}
复制代码
可以看出@EnableAutoConfiguration
也是一个复合注解,所以我们接下来对其关联的注解进行解析:
2.2.1 @AutoConfigurationPackage
该注解的作用是将添加该注解的类所在的package作为自动配置package 进行管理,也就是说当Spring Boot应用启动时默认会将启动类所在的package作为自动配置的package。老规矩,先看看其定义:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
&#