目录
微服务架构时代
快速入门
入门详解
SpringBoot的自动配置
石器时代:XML配置bean
青铜时代:SpringConfig
铁器时代:AutoConfigurationImportSelector
手写简单Starter
SpringApplication启动原理
微服务架构时代
Spring Boot的出现与微服务架构有关,它是Spring Framework的一部分,旨在简化开发独立的、可执行的Java应用程序。Spring Boot解决了传统Java应用程序开发中的繁琐配置问题,使开发人员能够更快速地构建微服务和独立应用程序。
快速入门
如果要快速入门,这个传送门一定很有帮助------->Spring | Quickstart
入门详解
Spring入门详解的部分诸君可以看一下这篇文章:
SpringBoot入门详解-CSDN博客
SpringBoot的自动配置
石器时代:XML配置bean
<?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.xsd">
<!-- 声明一个名为 myBean 的 Bean -->
<bean id="myBean" class="com.elaine.MyBean">
<property name="name" value="elaine"/>
</bean>
</beans>
青铜时代:SpringConfig
@Configuration
public class MyConfiguration {
@Bean
public MyBean myBean() {
MyBean bean = new MyBean();
bean.setName("Elaine");
return bean;
}
}
铁器时代:AutoConfigurationImportSelector
SpringBoot开启自动配置的注解是@EnableAutoConfiguration,但是自动配置的核心功能是通过AutoConfigurationImportSelector实现的。
@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 {};
}
-
AutoConfigurationImportSelector实现ImportSelector接口,收集需要导入的配置类,配合@Import将相应的类导入到Spring容器中。
-
获取注⼊类的⽅法是 selectImports(),它实际调⽤的是 getAutoConfigurationEntry ,这个⽅法是获取⾃动装配类的关键,主要流程可以分为这么⼏步:
-
获取注解的属性,用于后面的排除
-
获取所有需要⾃动装配的配置类的路径:这⼀步是最关键的,从 META-INF/spring.factories 获取⾃动 配置类的路径
-
去掉重复的配置类和需要排除的重复类,把需要⾃动加载的配置类的路径存储起来
-
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} else {
AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
}
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!this.isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
} else {
// 1.获取注解的属性
AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
// 2.获取需要⾃动装配的所有配置类,读取META-INF/spring.factories,获取⾃动配置类路径
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
// 3.1.移除重复的配置
configurations = this.removeDuplicates(configurations);
// 3.2.处理需要排除的配置
Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
this.checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = this.getConfigurationClassFilter().filter(configurations);
this.fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
}
手写简单Starter
在了解自动配置的原理后,就简单地创建一个自定义的spring-boot-starter吧。
文件目录贴一下:
-
创建自动配置类和需要定义的bean。
@Configuration public class MyUserAutoConfiguration { @Bean public UserManager userManager(){ return new UserManager(); } } public class UserManager { public String sayHello() { return "own-starter:hello."; } }
-
在
src/main/resources/META-INF/
目录下创建一个spring.factories
文件org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.lloyd.user.MyUserAutoConfiguration
-
创建一个spring-web的SpringBoot项目,添加自定义Starter的依赖。
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- 自定义starter的坐标 --> <dependency> <groupId>com.lloyd</groupId> <artifactId>springboot_06_own_starter</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
-
创建一个Rest接口进行验证
@RestController public class UserController { @Autowired private UserManager userManager; @GetMapping("/user") public String sayHello(){ return userManager.sayHello(); } }
浏览器结果:
SpringApplication启动原理
SpringApplication 这个类主要做了以下四件事情:
-
推断应⽤的类型是普通的项⽬还是 Web 项⽬
-
查找并加载所有可⽤初始化器 , 设置到 initializers 属性中
-
找出所有的应⽤程序监听器,设置到 listeners 属性中
-
推断并设置 main ⽅法的定义类,找到运⾏的主类
大致流程如下(图片来自于网络):