2.2 自动配置(启动流程)
概念:能够在我们添加 jar 包依赖的时候,自动为我们配置一些组件的相关配置,我们无需配置或者只需要少量配置就能运行编写的项目
问题:Spring Boot 到底是如何进行自动配置的,都把哪些组件进行了自动配置?
Spring Boot 应用的启动入口是 @SpringBootApplication 注解标注类中的 main() 方法,@SpringBootApplication 能够扫描 Spring 组件并自动配置 Spring Boot
下面,查看 @SpringBootApplication 内部源码进行分析,核心代码具体如下
java
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class, args);
}
}
java
@Target({ElementType.TYPE}) // 注解的适用范围,Type 表示注解可以描述在类、接口、注解或枚举中
@Retention(RetentionPolicy.RUNTIME) // 表示注解的生命周期,Runtime 运行时
@Documented // 表示注解可以记录在 javadoc 中
@Inherited // 表示可以被子类继承该注解
@SpringBootConfiguration // 标明该类为配置类
@EnableAutoConfiguration // 启动自动配置功能
@ComponentScan(// 包扫描器
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
…
}
从上述源码可以看出,@SpringBootApplication 注解是一个组合注解,前面 4 个是注解的元数据信息,我们主要看后面 3 个注解:@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan 三个核心注解,关于这三个核心注解的相关说明具体如下:
1.@SpringBootConfiguration 注解 **
@SpringBootConfiguration 注解表示 Spring Boot 配置类。查看 @SpringBootConfiguration 注解源码,核心代码具体如下。
java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration // 配置 IOC 容器
public @interface SpringBootConfiguration {
}
从上述源码可以看出,@SpringBootConfiguration 注解内部有一个核心注解 @Configuration,该注解是 Spring 框架提供的,表示当前类为一个配置类(XML 配置文件的注解表现形式),并可以被组件扫描器扫描。由此可见,@SpringBootConfiguration 注解的作用与 @Configuration 注解相同,都是标识一个可以被组件扫描器扫描的配置类,只不过 @SpringBootConfiguration 是被 Spring Boot 进行了重新封装命名而已
2.@EnableAutoConfiguration 注解
@EnableAutoConfiguration 注解表示开启自动配置功能,该注解是 Spring Boot 框架最重要的注解,也是实现自动化配置的注解。同样,查看该注解内部查看源码信息,核心代码具体如下
![image-20191226121755878](./images/image-20191226121755878.png)
可以发现它是一个组合注解,Spring 中有很多以 Enable 开头的注解,其作用就是借助 @Import 来收集并注册特定场景相关的 bean,并加载到 IoC 容器。@EnableAutoConfiguration 就是借助 @Import 来收集所有符合自动配置条件的 bean 定义,并加载到 IoC 容器。
下面,对这两个核心注解分别讲解 :
(1)@AutoConfigurationPackage 注解
查看 @AutoConfigurationPackage 注解内部源码信息,核心代码具体如下:
“`java
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class}) // 导入 Registrar 中注册的组件
public @interface AutoConfigurationPackage {
}
从上述源码可以看出,@AutoConfigurationPackage 注解的功能是由 @Import 注解实现的,它是 spring 框架的底层注解,它的作用就是给容器中导入某个组件类,例如 @Import(AutoConfigurationPackages.Registrar.class),它就是将 Registrar 这个组件类导入到容器中,可查看 Registrar 类中 registerBeanDefinitions 方法,这个方法就是导入组件类的具体实现 :
![image-20191226122946037](./images/image-20191226122946037.png)
从上述源码可以看出,在 Registrar 类中有一个 registerBeanDefinitions() 方法,使用 Debug 模式启动项目,可以看到选中的部分就是 com.lagou。也就是说,@AutoConfigurationPackage 注解的主要作用就是将主程序类所在包及所有子包下的组件到扫描到 spring 容器中。
因此 在定义项目包结构时,要求定义的包结构非常规范,项目主程序启动类要定义在最外层的根目录位置,然后在根目录位置内部建立子包和类进行业务开发,这样才能够保证定义的类能够被组件扫描器扫描
刚学了拉勾教育的《Java 工程师高薪训练营》,看到刚学到的点就回答了。希望拉勾能给我推到想去的公司,目标:字节!!