文章目录
1. 新建工程
- 新建maven工程:jar(quick start)
- 修改pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>springboot-01-helloworld</finalName>
<plugins>
<!-- 指定项目源码的jdk版本,编译后的jdk版本,以及编码 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<!-- 这个插件直接将应用打包成一个可执行的jar包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
- 主启动类
/*
* @SpringBootApplication标注一个主程序类,说明这是一个spring boot应用
* SpringApplication.run(xxx.class, args);必须运行的是被@SpringBootApplication注解标注的类
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
//启动spring应用
SpringApplication.run(HelloWorldMainApplication.class, args);
}
}
2. 依赖管理
导入spring-boot-starter不需要指定版本
- 在pom.xml指定了spring-boot-starter-parent的版本
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.10.RELEASE</version>
</parent>
- ctrl+左键进入,发现spring-boot-starter-parent依赖了spring-boot-dependencies
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.10.RELEASE</version>
<relativePath>../../spring-boot-dependencies</relativePath>
</parent>
- 继续ctrl+左键进入,发现spring-boot-dependencies帮助我们控制了依赖的版本
<properties>
<!-- Dependency versions -->
<activemq.version>5.15.10</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.76</appengine-sdk.version>
<artemis.version>2.6.4</artemis.version>
<aspectj.version>1.9.4</aspectj.version>
<assertj.version>3.11.1</assertj.version>
...
</properties>
3. 自动配置原理
3.1 @SpringBootApplication
标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot就应该运行这个类的main方法来启动SpringBoot应用
@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 {}
3.2 @SpringBootConfiguration
标注在某个类上,表示这是一个Spring Boot的配置类
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {}
@Configuration 表明是配置类,@Component添加为容器组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {}
3.3 @EnableAutoConfiguration
@AutoConfigurationPackage:自动配置包
@Import:Spring的底层注解,给容器中导入一个组件,导入的组件由 AutoConfigurationPackages.Registrar.class 将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器
EnableAutoConfigurationImportSelector.class:导入哪些组件的选择器;将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;还会给容器中导入非常多的自动配置类(xxxAutoConfiguration),通过配置类将这个场景需要的所有组件配置好
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {}
getAutoConfigurationEntry()方法执行时,会获取配置List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
可以看到这些配置全是xxxAutoConfiguration