之前有一篇文章讲述过创建springboot工程的方法(https://start.spring.io/),但是由于在实际开发中的习惯和一些方便,我分享下我自己从一个maven工程自行搭建一个springboot工程的实例,也是帮助大家能够更好的了解到springboot是怎样运行的。
1.我们先新建一个空的maven工程,因为在采用spring Initializr新建工程时候,会给我们新建一些无用东西。所以建议用纯净的模式新建。
2.然后输入工程的groupId和Artifactid点击next然后进行保存
然后可以看到新建成功了一个空的maven工程,如图所示
3.接下来需要我们进行pom文件的配置:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kk.demo</groupId>
<artifactId>SpringBootDemo</artifactId>
<version>1.0</version>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.4.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
我们知道在springboot启动的过程中只需要一个spring-boot-starter-web包
从这个pom文件中我们可以看到在spring-boot-starter-web中包含了 SpringMvc、Spring、Tomcat、json和hibernate校验等,具体是如何加载运行的我们后面会讲到,到这里pom文件的配置就全部配置完成了。
4.接下来我们创建工程的目录结构并且新建工程的启动类和application.yml
新建工程的配置文件application.yml
server:
port: 8080
servlet:
context-path: /spring-boot-demo
logging:
file: /home/kk/spring-boot-demo.log
新建工程的启动类SpringbootDemoApplication.java(这里说明一下,springboot的启动类的包必须放在外层中,即所以的java类全部在启动类的子包中)
package com;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
* 启动入口
* @author :Mr.kk
*/
@SpringBootApplication
public class SpringbootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootDemoApplication.class,args);
}
}
创建一个测试类TestController.java
package com.kk.demo;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author :Mr.kk
* @date: 2020/3/2 15:44
*/
@RestController
public class TestController {
@GetMapping("/testSpringBootDemo")
public String testSpringBootDemo(){
return "I am a test";
}
}
然后可以看到这个就是整个工程的目录结构图
然后我们启动工程可以看到,接口的返回数据
到此我们的整合就完成了,可以通过上图看到我们的工程结构和目录是清晰的,接下来我们就需要来总结下,springboot是如何通过上面的步骤进行运行的。
总结:
因为springboot的启动是从一个main方法开始的,那么我们先来看一下这个main方法。
@SpringBootApplication是一个复合注解:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
//一个spring注解,用来代替xml的配置
@SpringBootConfiguration
//自动装配的注解
@EnableAutoConfiguration
//扫描的包路径
@**ComponentScan**(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
@SpringBootConfiguration注解的代码如下,说明该注解是一个spring的注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@ComponentScan的代码可以看到,通过配置basepackage可以设备包的扫描路径
@EnableAutoConfiguration而自动装配的核心就是这个注解,我们可以看到这个注解也是一个复合注解
里面有通过@Import({AutoConfigurationImportSelector.class}) 引入了一个AutoConfigurationImportSelector类
selectImports方法中调用了如下的方法:
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
return configurations;
}
该方法loadFactoryNames()扫描所有具有META-INF/spring.factories的jar包,然后讲所有的自动加载类加载到spring容器中。
自动装配的生效条件
@ConditionalOnBean:当容器里有指定的bean的条件下。
@ConditionalOnMissingBean:当容器里不存在指定bean的条件下。
@ConditionalOnClass:当类路径下有指定类的条件下。
@ConditionalOnMissingClass:当类路径下不存在指定类的条件下。
@ConditionalOnProperty:指定的属性是否有指定的值,比如@ConditionalOnProperties(prefix=”xxx.xxx”, value=”enable”, matchIfMissing=true),代表当xxx.xxx为enable时条件的布尔值为true,如果没有设置的情况下也为true。
用一句话总结就是:
Spring Boot启动的时候会通过@EnableAutoConfiguration注解先找到META-INF/spring.factories配置文件中的所有自动配置类,并对其进行加载,而这些自动配置类都是以AutoConfiguration结尾来命名的,它实际上就是一个JavaConfig形式的Spring容器配置类,它能通过以Properties结尾命名的类中取得在全局配置文件中配置的属性,而XxxxProperties类是通过@ConfigurationProperties注解与全局配置文件中对应的属性进行绑定的。
代码路径
接下来我们会重新用一个工程来记录自定义一个配置类,并被别的工程依赖加载。