继上一篇我们搭建了一个非常简单的Spring Boot的demo。接下来,我们将继续学习Spring Boot的相关知识。闲话少叙。
本Spring Boot的版本是2.0.0.RELEASE
:
Dependency Management
继承 spring-boot-starter-parent
默认是:
Java 1.8
UTF-8
Resource filtering。exec plugin、surefire、Git commit ID、shade。
如果不想使用Spring Boot中的默认版本,可以再<properties>
覆盖相应的版本,如,想使用不同版本的Spring Data,具体如下:
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
想使用不同版本的JDK
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 使用 java 1.8 -->
<java.version>1.8</java.version>
</properties>
pom文件
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.RELEASE</version>
</parent>
不继承spring-boot-starter-parent
这种情况下,仍然可以使用dependency management
,但不能使用plugin management
方式如下:
<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>
注意,socpe 是import。而且,这种情况下,不再允许<properties>
覆盖相应的版本。如果要使用其他版本,需要在上面的前面添加一个完整的dependency
。如下:
<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>
Starters
可以创建自己的Starters,但名字格式不能是spring-boot-starter-*
,而是*—spring-boot-starter
。类似于Maven的插件。各种starter
自动配置
@Import和@ComponentScan 类似;
@EnableAutoConfiguration 和@SpringBootAppliction 类似;注意,只能使用一次,建议用在primary @Configuration class上
注意,自动配置永远都是第二位,一旦你配置了自己的东西,那自动配置的就会被覆盖。
禁用特定的自动配置:
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}
如果class不在classpath 中,可以使用excludeName
,然后使用全路径即可。
Spring Beans和依赖注入
@SpringBootApplication等同于默认属性的
@Configuration, @EnableAutoConfiguration and @ComponentScan。
– 注意,@ComponentScan 不能凭空使用。
@Service 用在业务层
@Controller 用在Controller层(控制层)
@Repository 用在数据层
@Autowired 用于注入bean
运行fat jar(executable jar)
java -jar target/xxx.jar
启动远程调试支持
java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar
使用Maven Plugin
mvn spring-boot:run
设置系统的环境值
export MAVEN_OPTS=-Xmx1024m
热加载
因为Spring Boot应用都是简单的Java应用,所以JVM Hot-swapping 可以直接使用,但是,JVM Hot-swapping 对于能够替换的字节码有些限制,所以建议使用JRebel 或者Spring Loaded
spring-boot-devtools 模块同样包含了快速重启应用的支持,但是只能在debug期间修改方法体。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
注意,生产环境下(java -jar 或者通过特定的类加载器启动),这些开发工具则自动被禁止。
上面的<optional>true</optional>
可以有效阻止用于其他模块。如果你想确保生产Build中不包含devtools,可以使用excludeDevtools build property。
Property defaults
一些Spring Boot 支持的库使用了caches 增强性能。例如, template engines。但是cache,在开发过程中可能会是一个阻碍,例如你无法立即更新一个模块(thymeleaf的)。cache 设置通常在application.properties中。但是,比起手动设置这些,spring-boot-devtools
模块会自动应用这些开发期的设置。
自动重启
使用spring-boot-devtools
模块的应用,当classpath中的文件有改变时,会自动重启!—就是说,默认会监视classpath入口。
静态资源和视图模板不需要重启!
注意,不同的IDE有不同的表现,例如Eclipse中只要改变了文件并保存,那么就会导致classpath中的内容改变,而IDEA则需要Build -> Make Project。
可以通过 build plugin 启动应用,只要开启了forking支持,因为Devtools需要一个隔离的classloader才能运行正常。Maven下要这样开启:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
</plugins>
</build>
注意:在使用LiveReload(热加载)时,自动重启仍然可以正常工作。如果你使用了JRebel,自动重启会被禁用以支持动态类加载。此时,devtools其他方面仍然可以使用。
注意:DevTools在重启过程中依赖应用上下文的shutdown hook来关掉它,所以如果禁用了shutdown hook,他就无法正常工作了。
SpringApplication.setRegisterShutdownHook(false)
Spring Boot使用的重启技术,实际上是使用了两个类加载器:不变的base类加载器,可变的restart 类加载器。前者加载第三方jar之类的。后者加载项目代码。重启的时候,只是丢弃可变的restart 类加载器,然后重新创建一个。所以速度比较快。
如果你还是觉得不够快,你可以考虑使用JRebel
一些特定的资源改变时没有必要引起重启。有一些不会引起重启,但是会重加载。如果你想自定义的设置一下,可以使用spring.devtools.restart.exclude
属性,例如,要排除/static
以及/public
,你可以设置如下属性。
spring.devtools.restart.exclude=static/**,public/**
如果你想在修改classpath之外的文件时也让应用重启,可以使用spring.devtools.restart.additional-paths
属性。还可以配合上面提到的spring.devtools.restart.exclude
属性,来控制是重启还是重加载。
如果不想使用自动重启功能,可以使用spring.devtools.restart.enabled
属性。多数情况下,可以再application.properties
中设置,这样仍然会创建一个restart类加载器。但不在监视改变。
如果想完全禁止自动重启,需要在调用SpringApplication.run(..) 之前设置一个System属性。如下:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
如果你的IDE可以随改随编译,你可能会倾向于只在特定时刻引发重启,这时,你可以使用trigger file
,就是一个特定的文件。只有修改了这个文件才会触发重启,使用spring.devtools.restart.trigger-file
属性即可。
自定义restart类加载器。
如果有一个多模块项目,只有部分导入到你的IDE中,你可能需要自定义一下。首先创建一个文件:META-INF/spring-devtools.properties。该文件中,可以有以前缀 restart.exclude. 和 restart.include. 开头的属性。前者会被放入base类加载器,后者则被放入restart类加载器。
该属性的value,是正则表达式。例如:
restart.include.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
已知限制
自动重启,在使用 ObjectInputStream
反序列化时,会出现问题。如果你需要反序列化数据时,你或许需要使用Spring的ConfigurableObjectStream
配合Thread.currentThread().getContextClassLoader()
使用。
可惜,一些第三方的jar没有考虑到这个问题。无解。
热加载LiveReload
spring-boot-devtools 模块内置了一个liveReload Server,可以保证在改变资源时浏览的刷新。LiveReload 的浏览器扩展,免费支持Chrome,Firefox以及Safari。
如果你想禁用 LiveReload server,你可以设置spring.devtools.livereload.enabled
属性为false。
注意:只能运行一个LiveReload Server。如果同时开启多个项目,那只有第一个。
引用
https://www.cnblogs.com/larryzeal/p/5799195.html#c4-3
https://docs.spring.io/spring-boot/docs/2.0.0.RELEASE/reference/htmlsingle/#getting-started-first-application-executable-jar