点击上方 **好好学java **,选择 **星标 **公众号
重磅资讯、干货,第一时间送达
重磅资讯、干货,第一时间送达
今日推荐:
个人原创100W+访问量博客:点击前往,查看更多
个人原创100W+访问量博客:点击前往,查看更多
SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂SpringBoot内部启动原理,以后难免会吃亏。所以这次博主就跟你们一起一步步揭开SpringBoot的神秘面纱,让它不在神秘。
那么接下,我们就通过SpringBoot源码分析,讲述启动原理
我们开发任何一个Spring Boot项目,都会用到如下的启动类
@SpringBootApplication
publicclassApplication {
publicstaticvoid main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
从上面代码可以看出,Annotation定义(@SpringBootApplication)和类定义(SpringApplication.run)最为耀眼,所以要揭开SpringBoot的神秘面纱,我们要从这两位开始就可以了。
一、SpringBootApplication背后的秘密
@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@interfaceSpringBootApplication {
...
}
@Configuration
@EnableAutoConfiguration
@ComponentScan
publicclassApplication {
publicstaticvoid main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
每次写这3个比较累,所以写一个@SpringBootApplication方便点。接下来分别介绍这3个Annotation。
1、@Configuration
(1)表达形式层面
基于XML配置的方式是这样:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
default-lazy-init="true">
<!--bean定义-->
</beans>
而基于JavaConfig的配置方式是这样:
@Configuration
publicclassMockConfiguration{
//bean定义
}
任何一个标注了@Configuration的Java类定义都是一个JavaConfig配置类。
(2)注册bean定义层面
基于XML的配置形式是这样:
<bean id="mockService"class="..MockServiceImpl">
...
</bean>
而基于JavaConfig的配置形式是这样的:
@Configuration
publicclassMockConfiguration{
@Bean
publicMockService mockService(){
returnnewMockServiceImpl();
}
}
任何一个标注了@Bean的方法,其返回值将作为一个bean定义注册到Spring的IoC容器,方法名将默认成该bean定义的id。
(3)表达依赖注入关系层面
为了表达bean与bean之间的依赖关系,在XML形式中一般是这样:
<bean id="mockService"class="..MockServiceImpl">
<propery name ="dependencyService"ref="dependencyService" />
</bean>
<bean id="dependencyService"class="DependencyServiceImpl"></bean>
而基于JavaConfig的配置形式是这样的:
@Configuration
publicclassMockConfiguration{
@Bean
publicMockService mockService(){
returnnewMockServiceImpl(dependencyService());
}
@Bean
publicDependencyService dependencyService(){
returnnewDependencyServiceImpl();
}
}
如果一个bean的定义依赖其他bean,则直接调用对应的JavaConfig类中依赖bean的创建方法就可以了。
@Configuration:提到@Configuration就要提到他的搭档@Bean。使用这两个注解就可以创建一个简单的spring配置类,可以用来替代相应的xml配置文件。
<beans>
<bean id = "car"class="com.test.Car">
<property name="wheel"ref = "wheel"></property>
</bean>
<bean id = "wheel"class="com.test.Wheel"></bean>
</beans>
相当于:
@Configuration
publicclassConf {
@Bean
publicCar car() {
Car car = newCar();
car.setWheel(wheel());
return car;
}
@Bean
publicWheel wheel() {
returnnewWheel();
}
}
@Configuration的注解类标识这个类可以使用Spring IoC容器作为bean定义的来源。
@Bean注解告诉Spring,一个带有@Bean的注解方法将返回一个对象,该对象应该被注册为在Spring应用程序上下文中的bean。
2、@ComponentScan
3、@EnableAutoConfiguration
@EnableAutoConfiguration作为一个复合Annotation,其自身定义关键信息如下:
@SuppressWarnings("deprecation")
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public@interfaceEnableAutoConfiguration {
...
}
自动配置幕后英雄:SpringFactoriesLoader详解
SpringFactoriesLoader属于Spring框架私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories加载配置。
publicabstractclassSpringFactoriesLoader {
//...
publicstatic <T> List<T> loadFactories(Class<T> factoryClass, ClassLoader classLoader) {
...
}
publicstaticList<String> loadFactoryNames(Class<?> factoryClass, ClassLoader classLoader) {
....
}
}
配合@EnableAutoConfiguration使用的话,它更多是提供一种配置查找的功能支持,即根据@EnableAutoConfiguration的完整类名org.springframework.boot.autoconfigure.EnableAutoConfiguration作为查找的Key,获取对应的一组@Configuration类。
二、深入探索SpringApplication执行流程
去除事件通知点后,整个流程如下:
本文以调试一个实际的SpringBoot启动程序为例,参考流程中主要类类图,来分析其启动逻辑和自动化配置原理。
总览
启动
SpringBoot启动类
首先进入run方法
run方法中去创建了一个SpringApplication实例,在该构造方法内,我们可以发现其调用了一个初始化的initialize方法
这里主要是为SpringApplication对象赋一些初值。构造函数执行完毕后,我们回到run方法
该方法中实现了如下几个关键步骤:
主要看其继承的两个方向:
自动化配置
之前的启动结构图中,我们注意到无论是应用初始化还是具体的执行过程,都调用了SpringBoot自动配置模块。
SpringBoot自动配置模块
工厂接口与其若干实现类接口名称
下图有助于我们形象理解自动配置流程。
SpringBoot自动化配置关键组件关系图
之前我们提到了EnableAutoConfiguration注解,其类图如下:
进入org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration中,主要看一下类头:
这里是截取的mybatis-spring-boot-starter的源码中pom.xml文件中所有依赖:
作者:平凡希
cnblogs.com/xiaoxi/p/7999885.html
推荐文章
原创电子书历时整整一年总结的 Java 面试 + Java 后端技术学习指南,这是本人这几年及校招的总结,各种高频面试题已经全部进行总结,按照章节复习即可,已经拿到了大厂offer。
原创思维导图扫码或者微信搜 程序员的技术圈子 回复 面试 领取原创电子书和思维导图。