简介

Spring Boot 根据实际的项目可以有不同的文件结构,比如使用maven还是使用gradle构建工具,开发Web项目还是控制台项目,使用JPA文件结构和使用Mybatis的文件结构,前后端分离项目它们采用的目录结构是不同的,但它们包含一个通用文件结构,这些文件是在Spring Boot中约定配置的。

学习环境

  • Spring Boot 2.2.7.RELEASE
  • Maven 3.6.0

Demo的项目结构

Demo创建了一个HelloWorld的项目,项目使用创建RESTful风格的接口,并在单元测试中测试该接口。

在IDEA中项目的结构

springboot项目软件系统架构图 springboot的项目结构_java


在IDEA中可以通过 File -> Project Structure -> Modules (Windows快捷键 Ctrl + Alt + Shift + s)来配置Sources。

springboot项目软件系统架构图 springboot的项目结构_springboot项目软件系统架构图_02

pom.xml

POM( Project Object Model,项目对象模型 ) 是 Maven 工程的基本工作单元,是一个XML文件,包含了项目的基本信息,用于描述项目如何构建,声明项目依赖,等等。参考 在Spring Boot 项目中pom文件为以spring-boot-starter-parent为父项目对一些常用包的版本进行管理,同时也提供了方便将项目打包成jar包的插件spring-boot-maven-plugin。

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <!--指定当前pom版本-->
    <modelVersion>4.0.0</modelVersion>
    <!--父项目标签。spring-boot-starter-parent 是一个特殊的starter,它用来提供相关的Maven默认依赖。使用它之后,常用的包依赖可以省去version标签-->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.7.RELEASE</version>
        <!--父项目的pom.xml文件的相对路径。本地有多个仓库相对路径允许你选择一个不同的路径。默认值是../pom.xml,在多模块项目中子模块可以使用默认值。Maven在构建时首先会在当前项目的地方寻找父项目的pom,其次在文件系统的这个位置(relativePath位置),然后在本地仓库,最后在远程仓库寻找父项目的pom-->
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <!--项目打包类型,jar、war、pom、ejb、ear、rar、par、maven-plugin, 默认是jar类型-->
    <packaging>jar</packaging>

    <!--项目相关信息-->
    <groupId>cn.makerknz</groupId>
    <artifactId>hello-world</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>hello-world</name>
    <description>Demo project for Spring Boot</description>

    <!--为pom定义一些常量,在pom中的其它地方可以直接引用-->
    <properties>
        <!--jdk版本-->
        <java.version>1.8</java.version>
    </properties>

    <!--项目开发过程中需要使用到外部包,包括Spring Boot项目包和第三方包-->
    <dependencies>
        <!--Spring Boot的核心启动器,包含了自动配置、日志和YAML-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <!--junit5不需要配置junit-vintage-engine-->
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <!--spring-boot-maven-plugin插件在打Jar包时会引入依赖包,当运行“mvn package”进行打包时,会打包成一个可以直接运行的 JAR 文件,使用“Java -jar”命令就可以直接运行。-->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Sources

开发的源码是放在Source Folder(src\main\java)中包路径(groupId + artifactId)下,必须要包含HelloWorldApplication启动类作为程序的入口,启动类通过@SpringBootApplication可以自动扫描项目中加载的包并根据配置将Bean及其所依赖的对象注入Spring容器中。调用run方法过程中执行了计时程序的启动时间,Spring 运行时事件监听,始化输入参数、配置环境,输出banner,创建上下文,预处理上下文,刷新上下文,再刷新上下文、发布应用已经启动事件、发布应用启动完成事件一系列操作,在刷新上下文中启动web容器(Tomcat,Jetty或undertow)和将Bean加载到容器。

@SpringBootApplication
@RestController
public class HelloWorldApplication {

    public static void main(String[] args) {
        SpringApplication.run(HelloWorldApplication.class, args);
    }

    /**
     * 通过浏览器访问http://localhost:8080/hello-world可以在页面中渲染出大标题的Hello world!
     * @return
     */
    @GetMapping("/hello-world")
    public String helloWorld() {
        return "<h1>Hello world!</h1>";
    }

}

Test Sources

开发的测试源码是放在Test Source Folder(src\test\java)中包路径(groupId + artifactId)下,@SpringBootTest后,Spring将加载所有被管理的bean,基本等同于启动了整个服务。

@SpringBootTest
class HelloWorldApplicationTests {

    @Autowired
    private WebApplicationContext wac;

    @Test
    void contextLoads() throws Exception {
        MockMvc mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();

        // MockMvcRequestBuilders构建GET请求
        String result = mockMvc.perform(MockMvcRequestBuilders.get("/hello-world")
                .accept(MediaType.TEXT_HTML_VALUE))
                //返回请求的字符串信息
                .andReturn().getResponse().getContentAsString();

        System.out.println(result);
    }

}

resources

配置

Spring Boot使用一个全局的配置文件名是application,在全局配置之前还有bootstrap命名的文件用于应用程序上下文的引导阶段,配置文件有两种格式properties和yaml,但内容的本质都是Key-Value的格式,如果使用多个profile可以使用可以使用application-${profileName}。
配置文件加载位置和加载顺序可以自己查找。

static

static中放置的是静态页面,Spring Boot 项目启动后可以通过服务器http://localhost:8080/ + 静态页面(包含路径)访问。

templates

templates中放置的是渲染的模板,动态页面需要先请求服务器,访问后台应用程序,然后再转向到页面,比如访问JSP。spring boot建议不要使用JSP,默认使用Thymeleaf来做动态页面。

target 文件夹

打包完成后jar包会生成到target目录下,命名一般是 项目名+版本号.jar。

其它文件

.idea

.idea存放项目的配置信息,包括历史记录,版本控制信息等。

hello-world.iml

iml是 intellij idea的工程配置文件,里面是当前project的一些配置信息。

HELP.md

Markdown的文本格式,可以写一些快速启动和配置的文档,和README.md类似。

总结

在一个Spring Boot通用文件结构中,每一个文件夹或文件都有其指定的功能。

参考

Spring Boot内置tomcat启动原理Spring Boot项目结构及功能Spring Boot 中配置文件的优先级和加载顺序