读书笔记1-独立的Spring应用

理解独立的Spring应用

​ 在SpringBoot编程思想一书中,本章着重介绍了SpringBoot项目的命令行以及图形界面创建方式,SpringBoot项目、jar包、war包等的目录结构,以及最重要的SpringBoot应用是如何通过jar包以及war包方式运行的。

创建SpringBoot项目

​ 介绍了如何通过命令行中的maven命令来创建springboot项目以及spring官网的图形界面创建方式创建项目。并且使用maven的方式来编译运行项目(而不是jar包或war包)。

命令行创建

通过Maven Archetype插件(一种创建Maven模板项目的工具)来创建。

1.创建基本mvn项目

利用默认的基本mvn模板来创建一个基本的mvn项目。

mvn archetype:generate -DgroupId=cn.xxx -DartifactId=springboot-project -Dpackage=cn.xxx.springboot.project -Dversion=1.0.0 -DinteractiveMode=false 

groupId:开发团队的统一标识,一般使用两段,第一段代表域,类似org、com、cn等,第二段代表公司名称或者团队名称。

artifactId:可以简单理解为实际的项目名称。

package:生成项目的默认包名,一般为GroupId+ArtifactId的组合。

version:版本号标识。

interactiveMode:是否为交互式创建。

2.添加SpringBoot依赖

在项目中的pom.xml文件中添加Spring Boot Web依赖以及Spring Boot Parent POM。

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <!--添加SpringBoot Parent POM-->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
  </parent>

  <groupId>cn.xxx</groupId>
  <artifactId>springboot-project</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0</version>
  <name>springboot-project</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    
    <!--添加springboot web 依赖-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.2.0.RELEASE</version>
    </dependency>

    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

3.添加启动代码

在自动生成的APP.java类上添加启动代码,使其成为启动类。

@RestController
@SpringBootApplication //主要启动注解
public class App {
    
    @RequestMapping("/")
    public String index() {
        return "Welcome to my project!";
    }
    
    public static void main( String[] args ) {
        SpringApplication.run(App.class,args); //主要启动代码
    }
}

4.启动项目

在项目路径下使用mvn spring-boot:run命令即可运行此项目。

图形化创建

在https://start.spring.io网站下即可快速的创建Spring Boot项目。

1.生成项目

在网站首界面填好group,artifact,以及添加dependencies中的web即可生成项目。

2.项目结构

src:

​ 存放源码,测试源码,资源文件。

.gitignore:

​ 定义了git的版本控制忽略名单。

.mvn、mvnw、mvnw.cmd:

​ 简单的maven构建方式,无需在运行环境提前安装mavne二进制文件。

.mvn/wrapper中的jar用于从maven官方下载maven二进制文件,properties文件在jar下载失败时,定义了下载的url。

mvnw和mvnw.cmd为引导.mvn中的jar下载mvn二进制文件用的脚本,分别对应linux和windows平台。

3.启动项目

​ 在linux平台下通过,sh mvnw spring-boot:run命令即可下载maven并运行项目。

:此启动方式属于开发环境启动方式,生产环境一般通过jar/war包方式启动。

创建并执行jar包

添加打包plugin到pom.xml

​ 构建SpringBoot项目可执行jar包的前提是需要添加spring-boot-maven-plugin到pom.xml中。

:图形化创建的项目中包含了此plugin,无需添加。

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.0.RELEASE</version>
  </parent>
  <groupId>cn.xxx</groupId>
  <artifactId>springboot-project</artifactId>
  <packaging>jar</packaging>
  <version>1.0.0</version>
  <name>springboot-project</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.2.0.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--添加SpringBoot的打包插件-->
  <build>
  	<plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
     </plugins>
  </build>
  <!---->
</project>

执行mvn打包命令

​ 在项目路径下的命令行中执行mvn package命令即可。

运行jar包

​ 命令行执行java -jar jar包路径即可运行此jar包。

SpringBoot中的Jar

jar包结构

在运行mvn打包命令后在项目的target/目录下会出现:

项目名-版本号.jar项目名-版本号.jar.original两个文件。

项目名-版本号.jar.original

这个文件是mvn打包的原始jar文件

路径结构:

/类路径 储存的是编译后的class文件

/META-INF 储存的是元信息

项目名-版本号.jar

这个文件是original文件经过mvn加工后的jar包,引入了第三方依赖资源。

路径结构:

/BOOT-INF/classes 储存的是编译后的class文件

/BOOT-INF/lib 储存的是依赖的第三方jar包

/META-INF 储存的是元信息

/org 存放的是SpringBoot相关的class文件

与传统jar的区别

springboot项目经过mvn打包出来的jar包中除了META-INF与传统jar包相同外,其它结构与传统jar包并不相同,其结构更像传统的web项目的war包。

jar包是如何运行的

既然SpringBoot的jar包结构与传统jar包并不相同,那么java -jar命令是如何运行它的呢?

java -jar命令启动类配置文件

java -jar的引导启动类是配置在/META-INF/MANIFEST.MF文件中的 MAIN-Class属性中的。

SpringBoot项目jar包配置的jar启动引导类为:

Main-Class: org.springframework.boot.loader.JarLauncher

jar包引导类

MANIFEST.MF文件中配置的启动引导类正是在jar包的\org\springframework\boot\loader\路径下的JarLauncher.class类

此类是由mvn pom中配置的plugin插件repackage jar.original时加入进去的。

JarLauncher类的职责

​ 引导并加载MAINIFEST.MF中配置的Start-Class类(也就是加springboot注解的那个springboot启动类)。

​ 配置classpath,使BOOT-INF/lib下的第三方jar包能够被找到。

jar包引导类介绍

public class JarLauncher extends ExecutableArchiveLauncher {
    static final String BOOT_INF_CLASSES = "BOOT-INF/classes/"; //类路径
    static final String BOOT_INF_LIB = "BOOT-INF/lib/";         //第三方依赖jar路径

    public JarLauncher() {
    }

    protected JarLauncher(Archive archive) {
        super(archive);
    }

    protected boolean isNestedArchive(Entry entry) {
        return entry.isDirectory() ? 
            entry.getName().equals("BOOT-INF/classes/") : 			        
        	entry.getName().startsWith("BOOT-INF/lib/");  //判断是否以其开头来判断是jar包还是解压后的文件
    }

    public static void main(String[] args) throws Exception {
        (new JarLauncher()).launch(args);  //启动类引导
    }
}

JarLauncher既支持jar包 也支持解压后的jar包运行。

JarLauncher在同进程内调用Start-Class类的main方法,并在启动前准备好ClassPath。

证明与源码分析请看书P41-P54页。

SpringBoot的War与Jar区别

WAR包结构

/WEB-INF/classes 储存的是编译后的class文件

/WEB-INF/lib 储存的是依赖的第三方jar包

/WEB-INF/lib-provided 储存的是pom中被provided的依赖

/META-INF 储存的是元信息

/org 存放的是SpringBoot相关的class文件

因为Sevlet容器只关心WEB-INF下的classeslib,所以lib-provided会被忽略转而使用Servlet容器自带的api来实现,如Servlet API。

因此这样设计WAR包既可以通过WarLauncher引导运行,也可以在Servlet容器中运行。

的是依赖的第三方jar包Jar的类似,因此不再介绍,只有路径区别且WarLauncher会加载lib-provided中的依赖。

发布了27 篇原创文章 · 获赞 1 · 访问量 903

猜你喜欢

转载自blog.csdn.net/hu853996234/article/details/103334466