欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

跟着官方文档学 SpringBoot 二:使用 spring boot

程序员文章站 2022-07-10 15:26:38
...

 

使用 spring boot

本文会更加深入使用 spring boot 的细节,包含 如何构建应用,自动配置以及启动应用几个话题。尽管 spring boot 并没有太多特殊的地方(其实你可以把它当作一个类库使用),只是如果有如下的一些提示,开发过程会更简单而已。

 

一、【应用构建】

强烈建议使用支持依赖管理的构建工具,提议使用 Maven 或者 Gradle。也可以使用其他构建系统,如 Ant,但是它们并没有得到 spring boot 很好的支持。

 

1.1 依赖管理

每一次 spring boot 版本的推出都会提供该版本支持的依赖列表。在实践中,你不需要为配置的依赖提供版本号(想这么做也可以)。当项目升级 spring boot 版本时, 这些依赖也会随之持续升级。

每个 spring boot 版本都关联一个基础的 spring framework 版本,最好不要手动指定 spring 版本。

 

1.2 Maven

Maven 用户可以从 spring-boot-starter-parent 项目继承,从而获得良好的默认配置。这个项目有一下特点:

  • Java 1.8 作为默认编译版本
  • 使用 UTF-8 编码
  • 从 spring-boot-starter-parent 继承,这使得你可以忽略版本号(version)标签
  • 良好的资源文件过滤(resource filtering)
  • 良好的插件配置
  • 对 application.properties 和 application.yml 进行资源过滤,包括特定于配置文件的文件(例如,application-dev.properties 和 application-dev.yml)

需要注意,由于 application.properties 和 application.yml 文件支持 spring 风格的占位符“${...}”,Maven 的占位符改为“@...@”。通过设置一个叫“resource.delimiter”的 maven 属性可以修改这个符号。

 

1.2.1 继承父工程

这个现在我们已经非常熟悉了,只需要注意版本标签即可

<version>2.0.0.RELEASE</version>

 想要知道 spring boot 都支持哪些依赖,依赖的写法,可以上网找答案,也可以点这里查找。

 

1.2.2 不继承父工程

所谓众口难调,并不是所有人都满意使用父工程的配置,也可能企业有自己的标准,需要自己明确声明 maven 配置。

那么不继承父工程,可以这样做

<dependencyManagement>
		<dependencies>
		<dependency>
			<!-- Import dependency management from Spring Boot -->
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.0.0.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

 通过将范围(scope)指定为“import”,这样可以保持 spring boot 良好的配置(不包括插件管理)。

那如何修改 spring boot 已经默认指定的依赖版本?比如,修改 spring data releasetrain 版本。

方法:增加你要修改的依赖,注意,要在 spring-boot-dependencies 声明之前,同时,将 scope 设置为 import 即可,如下

<dependencyManagement>
	<dependencies>
		<!-- Override Spring Data release train provided by Spring Boot -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-releasetrain</artifactId>
			<version>Fowler-SR2</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-dependencies</artifactId>
			<version>2.0.0.RELEASE</version>
			<type>pom</type>
			<scope>import</scope>
		</dependency>
	</dependencies>
</dependencyManagement>

 

1.2.3 使用 spring boot Maven 插件

spring boot 包含了一个可以将工程打包为可执行 jar 的 maven 插件。如下使用即可

<build>
	<plugins>
		<plugin>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-maven-plugin</artifactId>
		</plugin>
	</plugins>
</build>

 

1.3 那些“Starters”

“Starters”是一些依赖描述符的集合。简单来说,一个“Starters”声明的依赖可能包含了许多的分散的依赖,在以前,我们可能需要定义许许多多的 maven 坐标来引入依赖,无法避免地,需要从网上七拼八凑的复制粘贴,spring boot 的 “Starts”就解决了这个问题。

如果你要使用 spring 和 spring JPA 作为数据库访问技术,那么你只要声明 spring-boot-starter-data-jpa 依赖就 ok 了。

如果想要使用某个依赖,但不知道明确名称是什么,那么可以在 pom 文件中使用“spring-boot-starter-”作为前缀寻找。

 
跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
 

二、【代码构建】

spring boot 并不要求任何特殊的代码分层,即使如此,还是有一些有帮助的好的实践方式。

 

1.1 不要使用“default”包

当一个类没有包括一个包的声明,它会被放置于默认包中。默认包是不推荐使用,也是应该避免的。这对于 spring boot 应用可能造成一些问题,如果使用 @ComponentSacn,@EntityScan 或者 @SpringBootApplication 注解的话, 因为每个 jar 包中的每个类都会被读取。

 

1.2 启动类的位置

推荐将应用启动类(SpringApplication.run()所在的那个类)放置于根包(root package)目录下。

一个典型的目录分层如下:


跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
 

上图中的 Application.java 声明了 main 方法,并且使用了 @Configuration,如下

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

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

}

 1.3 配置类

spring boot 推崇基于 Java 的配置方式。尽管可以通过 XML 文件的方式开发 spring 应用,但是一般还是推荐将你的主要资源作为一个 @Configuration 注解的类。通常,定义了 main 方法的类是作为主要资源配置类的选择。

 

1.3.1 导入其他配置类

你无需将所有的配置都放在一个类中。@Import 注解可以用来导入其余的配置类。此外,也可以使用 @ComponentScan 来自动识别 spring 组件,包括 @Configuration 注解的类。

 

1.3.2 导入 XML 配置

如果一定要使用 XML 配置文件,可以通过将一个类用 @Configuration 注解,然后使用 @ImportResource 注解来加载 XML 配置文件。

 

1.4 自动配置

你需要在 其中一个配置类(@Configuration classes)中添加 @EnableAutoConfiguration 或者 @SpringBootApplication 注解,这样即可开启自动配置。需要注意的是,@EnableAutoConfiguration 注解应该只使用一次,因此推荐在主配置文件上添加。

 

1.4.1 替换自动配置

Auto-configuration 是无侵入性的,你可以定义自己的配置来替换自动配置的部分。比如,添加 DataSource bean(数据源类),那么默认的数据库支持就会失效了。

可以通过在启动项中加入“--debug”选项,你将会得到一个“条件评估报告”,它显示了哪些配置正在使用和为什么使用,哪些没有在使用等等:


跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
 
 1.4.2 禁用某些自动配置类

如果发现有你并不想要配置的类被应用了,可以使用 @EnableAutoConfiguration 的排除属性。

如下案例:

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

 如果需要被排除的类不在 classpath 中,可以使用该注解的 excludeName 属性,并指定类的全限定名。此外,还可以通过使用 spring.autoconfigure.exclude 属性来控制要排除的自动配置类的列表。

 

1.5 spring bean 和 依赖注入

在 spring boot 中,你可以随意地使用 spring 框架的标准技术,比如说使用 @ComponentScan 来发现 bean,使用 @Autowired 进行注入。如果你将代码做了如上文建议的构建(将启动类放在根包),那么你可以只添加 @ComponentScan 注解即可,不必加任何参数。所有的 spring 应用组件都将会被作为 spring bean 自动注册。

下面这个示例展示了一个 @Service bean 通过构造注入获得一个 RiskAssessor bean 的过程:

package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DatabaseAccountService implements AccountService {

	private final RiskAssessor riskAssessor;

	@Autowired
	public DatabaseAccountService(RiskAssessor riskAssessor) {
		this.riskAssessor = riskAssessor;
	}

	// ...

}

 如果一个 bean 只有一个构造方法,你也可以忽略 @Autowired 注解,但是要注意, RiskAssessor 是被 final 修饰的:

@Service
public class DatabaseAccountService implements AccountService {

	private final RiskAssessor riskAssessor;

	public DatabaseAccountService(RiskAssessor riskAssessor) {
		this.riskAssessor = riskAssessor;
	}

	// ...

}

 

1.6 使用 @SpringBootApplication

很多的开发人员都会将 @Configuration,@EnableAutoConfiguration 和 @ComponentScan 放在一起使用,因此,spring boot 提供了 @SpringBootApplication 这么个方便的注解。@EnableAutoConfiguration 和 @ComponentScan 都有自己的属性,在 @SpringBootApplication 也有相应的属性可以设置。

 

1.7 启动应用

以下基于上一篇“原生Hello World”案例演示。

1.7.1 在开发工具中启动

在本系列第一篇“准备”中,我们已经写过一个示例“Hello World”,我们将它导入到开发工具中来。如果无法直接导入,请检查开发工具中是否安装了 maven 插件。导入完成之后,直接点击 debug 按钮即可启动(或者 run)。

1.7.2 作为打包应用启动

这种方式在上一篇中提到过,在 pom 文件所在目录,执行以下命令即可:

java -jar target/myapplication-0.0.1-SNAPSHOT.jar

 也可以在启用远程调试支持的情况下运行打包的应用程序,这样可以将调试器附加到打包的应用程序:

java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
     -jar target/myapplication-0.0.1-SNAPSHOT.jar

 1.7.3 使用 Maven 插件启动(推荐)

以 Idea 工具为例,有两种方式可以通过 Maven 插件运行程序。

① 点击最右侧的“Maven Projects”,选择“myproject>Plugins>spring-boot>spring-boot:run”进行启动:


跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
 

②  通过添加新的 maven 配置,并在命令行中输入指令:


跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
 

1.8 开发者工具(Developer Tools)

spring-boot-devtools 模块提供了额外的开发阶段的特性,它所需要声明的依赖如下:

<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<optional>true</optional>
	</dependency>
</dependencies>

 

 1.8.1 默认的属性

许多类库都会使用缓存来提高响应性能,比如一些模版引擎会缓存编译好的模版,避免重复解析模版文件;比如 Spring MVC 在处理静态资源时,可以将 HTTP 缓存头添加到 response 中。这些对于用户友好的性能在开发中却往往适得其反,因为我们总是想要及时看到那些被我们修改过的东西。因此,在 spring-boot-devtools 中已经默认禁止了缓存。

 

缓存是否启用的选项往往会写在 application.properties 文件中,比起手动设置这些值,spring-boot-devtools 会自动应用开发阶段的配置。点击这里查看详细的默认配置。

 

1.8.2 自动重启

使用 spring-boot-devtools 模块后,当 classpath 路径中的文件(多指配置文件)发生改变时,应用(服务器)会自动重启,这对于开发阶段的调试会提高很大效率。对于一些静态资源的修改,并不需要重启应用,默认情况下,/META-INF/maven,/META-INF/resources,/resources,/static,/public 目录下的资源修改不会触发重启。如果浏览器添加了 live load 扩展,则会触发浏览器的刷新。

可以通过在配置文件中自定义不触发重启的资源位置,比如:

spring.devtools.restart.exclude=static/**,public/**

 如果想在默认的配置上再添加其他目录,可以这样配置:

spring.devtools.restart.additional-exclude=/js/**,/img/**

 如果不想启用 live load,可以将 spring.devtools.livereload.enable 设为 false。

1.8.3 其他路径上的改变

如果想要当其他路径(非 classpath)上的文件发生改变重启应用,需要使用spring.devtools.restart.additional-paths 属性指定。

 

1.8.4 禁用重启

在配置文件中指定 spring.devtools.restart.enabled 属性值为 false。如果因为重启应用这个特性,与第三方类库不兼容,需要彻底禁用,则需要在 SpringApplication.run() 方法前设置系统属性为 false,如下:

public static void main(String[] args) {
	System.setProperty("spring.devtools.restart.enabled", "false");
	SpringApplication.run(MyApp.class, args);
}

 

1.8.5 选择触发文件

使用开发工具开发时,往往会持续性地编译经过修改的文件,那么可能不太希望服务器太频繁重启。我们可以在配置文件中指定 spring.devtools.restart.trigger-file 的值,其值为触发文件的路径。最好将该文件作为全局设置,这样触发文件的修改会应用到整个项目。

 

如何设置为全局文件?

 

在“家目录($HOME)”文件夹下创建一个名为“.spring-boot-devtools.properties”属性文件,在该文件中添加以下内容即可:

spring.devtools.reload.trigger-file=.reloadtrigger

 简单解释下“家目录”:在 windows 系统中,Vista 及以上版本的家目录位于 <根目录>\Users\<用户名>,根目录为系统盘符,如我的系统盘为 C 盘;在 Linux 系统中,家目录位于 ~/ 下,这个想必大家都知道。

 

1.8.6 定制重启类加载器

在开始这个小节之前,我们先简单了解一下 “Restart” 和 “Reload” 有哪些不同之处。

restart 技术是由 spring boot 提供的,它通过使用两个类加载器实现。项目中的类无非分为两种,一种是第三方 jar,另一种就是我们开发的类。在绝大多数情况下,第三方 jar 是不变的,spring boot 把它们加载到 “base classloader”中,自己开发的类(经常改动) 加载到 “restart classloader” 中。当应用 restart 后,已经加载过类的 restart classloader 会被丢弃,并重新创建一个。因为 base classloader 不用重新加载类,相比起 reload 会快许多。

 回到本小节。为什么要定制重启类加载器呢?在很多应用中,通过使用这两种类加载器实现的重启可以正常发挥作用,但是在多模块应用中,由于并不是每个模块都会导入到开发工具中来,有时候会出现问题,那么就需要我们做一些定制的工作。

 

在 META-INF 下创建一个名为“spring-devtools.properties” 的属性文件,其中的属性名前缀 为 restart.excluderestart.include。include 元素对应的值意味着哪些类(或 jar)会被加载到 restart classloader 中,exclude 元素对应的则表示被加载到 base classloader 中。键必须唯一。

示例如下,属性的值是一个相对于 classpath 的正则表达式

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

 

1.8.7 重启功能的局限

重启功能对于那些使用标准的 ObjectInputStream(对象输入流) 反序列化的对象支持的不太好。如果想要反序列化数据,需要结合使用 spring 提供的 ConfigurableObjectInputStream 和 Thread.currentThread().getContextClassLoader()。

 

不巧的是,某些第三方类库做反序列化操作时没有考虑到 context classloader。如果遇到这样的问题,你需要向类库作者反馈并请求解决。

 

1.9 远程操作

待补充...

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
  • 描述: starts_search
  • 大小: 25.3 KB
  • 跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
  • 大小: 9.9 KB
  • 跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
  • 大小: 12.2 KB
  • 跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
  • 大小: 46.4 KB
  • 跟着官方文档学 SpringBoot 二:使用 spring boot
            
    
    博客分类: SpringBoot springboot 
  • 大小: 21.8 KB
相关标签: springboot