< 上一篇 :springboot项目实战(1)环境准备和服务运行(本地+服务器)
返回目录:springboot系列学习计划
- 在上一篇博客第一个疑问的解答:
- 阅读源码或者官方文档中遇到的生词,可点击查看此文档,粉丝免费。
1.官方文档和源码同样重要,一个给你提供广度,一个提供深度
2.博客中最后采用一段一段式翻译,大家如果英语欠佳,可以自己先翻译一遍,在看我翻译的(水平有限),篇幅较长。能力强的可以略过。
3.本来打算单独做一版官方文档全部翻译,一来是网上这种资源很多,二来有点本末倒置,太花时间,现在是遇到文档中的知识点,拿过来这一小节进行翻译(原文档地址会在具体位置给出)
一、 主启动的位置和原理
- 上篇实践中,将主启动类放在了B包下,访问时候报错,原因是没有扫描到controller包,无法注入相应的bean。
在上图中,放在A包目录下,是可以访问到的,或者放在更上一级的目录,B处是无法扫描到A处的bean的,C这个位置为classpath,一般把启动类放在这个包下。
- springboot包扫描的原理
官方文档描述:https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-structuring-your-code
Structuring Your Code
Spring Boot does not require any specific code layout to work. However, there are some best practices that help.
-- 构建你的代码
springboot 不需要特定的代码布局 来工作,然而,这里有些最佳实践可以提供帮助
2.1. Using the “default” Package
-- 使用 “默认”的包
When a class does not include a package declaration, it is considered to be in the “default package”. The use of the
“default package” is generally discouraged and should be avoided. It can cause particular problems for Spring Boot
applications that use the @ComponentScan, @ConfigurationPropertiesScan, @EntityScan, or @SpringBootApplication
annotations, since every class from every jar is read.
We recommend that you follow Java’s recommended package naming conventions and use a reversed domain name (for
example, com.example.project).
-- 当一个类不在一个包的声明下,那么我们认为i他在默认的包下,使用
默认的包通常是不被提倡,应该是被避免的,他会在实际的springboot项目中造成问题
当我们使用这些扫描注解(组件扫描,配置扫描,实体类扫描,SpringBoot应用程序等注解)
当所有的类都应该被读到的时候。
我们推荐你跟随Java推荐的包命名约定:使用倒过来的域名命名(如com.example,project)。
2.2. Locating the Main Application Class
-- 定位到主启动类
We generally recommend that you locate your main application class in a root package above other classes. The
@SpringBootApplication annotation is often placed on your main class, and it implicitly defines a base “search package”
for certain items. For example, if you are writing a JPA application, the package of the @SpringBootApplication annotated
class is used to search for @Entity items. Using a root package also allows component scan to apply only on your
project.
-- 我们通常推荐你将主启动类放置到应用的根包下,在其他的的上层。
@SprinigBootApplication 这个注解通常放在主启动类上,并且它隐式的定义了一个基本的搜索包名
(对于某些项目)。例如,如果你在写一个jpa(Java Persistence API)项目,写了@SpringBootApplication注解的类所在的
包,用于搜索实体类。用根目录包同样允许组件扫描在你的项目中
If you don’t want to use @SpringBootApplication, the @EnableAutoConfiguration and @ComponentScan annotations
that it imports defines that behaviour so you can also use those instead.
The following listing shows a typical layout:
--如果你不想使用@SpringBootApplication,可以使用@EnableAutoConfiguration和@ComponentScan注解替代,
他们同样可以定义这种行为, 下面列举了典型的布局:
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
The Application.java file would declare the main method, along with the basic @SpringBootApplication, as follows:
主启动类应该声明一个main方法,伴随着@SpringBootApplication注解
代码示例:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
- 默认的扫描包就是上述典型布局中的【com.example.myapplication】,下面从源码的角度看看这个值是怎么读取到的
1.上图中通过注解一级一级找到类Registrar.class
2.点击register方法:
类似springmvc 的配置文件和spring的xml配置文件都可以配置包扫描,如下:
只不过springboot是隐式的配置basepackage,即启动类所在的包<context:component-scan base-package="com.xxx"/>
拓展:上述验证的时@SpringBootApplication注解,当在某个类上@EnableAutoConfiguration也存在时,也会走上述同样的自动扫描过程 - 自动配置bean
springboot 扫描当前 classpath 下所有的 jar 包,筛选出来EnableAutoConfiguration 下的所有自动配置类注入到 spring 容器中,完成自动的 bean 的配置
这里的bean的默认配置都在类中,同样我们如果要修改,可以简便的通过配置文件来自定义值,只需要知道相应的key即可,我们采用application.yml或者application.properties来配置。
二、热部署(automatic restart)和强刷浏览器(liveReload)
上一节来到了配置文件,为了更直观的看到配置文件对程序的影响,引入热部署概念,不用频繁重启,更方便
①热部署(automatic restart)
引入devtools 详情可查看官方文档 https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-devtools
官方文档:
- Spring Boot includes an additional set of tools that can make the application development experience a little more pleasant. The spring-boot-devtools module can be included in any project to provide additional development-time features. To include devtools support, add the module dependency to your build, as shown in the following listings for Maven and Gradle:
<springboot 包含了一个额外的配置工具可以是应用开发者开发更愉快,这个开发工具模块可以被嵌入所有的项目中去提供额外的开发期特性。为了添加开发工具支持,需要在maven/gradle中添加依赖:<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies>
- Developer tools are automatically disabled when running a fully packaged application. If your application is launched from java -jar or if it is started from a special classloader, then it is considered a “production application”. If that does not apply to you (i.e. if you run your application from a container), consider excluding devtools or set the -Dspring.devtools.restart.enabled=false system property.
开发者工具当全量打包时会自动失效,如果你是使用java -jar命令运行的,或者是从一个特殊的类加载器加载的,那么他会被认定为是一个生产应用工具,如果这种工具不适用于你(或者在一个容器中运行),可以考虑去除devtools或者设置重启失效(-Dspring.devtools.restart.enabled=false ) - Applications that use spring-boot-devtools automatically restart whenever files on the classpath change. This can be a useful feature when working in an IDE, as it gives a very fast feedback loop for code changes. By default, any entry on the classpath that points to a directory is monitored for changes. Note that certain resources, such as static assets and view templates, do not need to restart the application.
应用程序使用的开发者工具自动重启(热部署),当文件在classPath下被改变即生效。它在使用IDE中开发中是一个非常有用的特性,因为其循环查找代码的变化并迅速给出反馈。默认情况下,任何在classpath下的实体所在的文件夹都在被监控着变化,注明的某些资源,如静态资源和视图模板,是不需要自启动的 - Triggering a restart
As DevTools monitors classpath resources, the only way to trigger a restart is to update the classpath. The way in which you cause the classpath to be updated depends on the IDE that you are using. In Eclipse, saving a modified file causes the classpath to be updated and triggers a restart. In IntelliJ IDEA, building the project (Build +→+ Build Project) has the same effect.
触发重启:
由于开发者工具监听这classpath资源,想要触发重启的方式就是更新这些资源。不同的IDE会有不同的触发方式,eclipse中保存修改后的文件即可更新并且触发重启。在IJ中构建项目可以达到同样效果
5.热部署原理
The restart technology provided by Spring Boot works by using two classloaders. Classes that do not change (for example, those from third-party jars) are loaded into a base classloader. Classes that you are actively developing are loaded into a restart classloader. When the application is restarted, the restart classloader is thrown away and a new one is created. This approach means that application restarts are typically much faster than “cold starts”, since the base classloader is already available and populated.
这个重启的技术源于springboot是由两个类装载器一起工作的。不会修改的类(如第三方的jar包)是被加载到基础类加载器中。类在开发中的会被加载到重启类加载器。当一个应用重启,这个重启类加载器被弃用,而一个新的加载器被创建。这种方式意味着应用重启通常会比“冷启动”快,前提是基础类加载器已经可用并且构建好。
补充:如下图:
实际操作
1. pom中添加依赖;
2. 勾选Build project automatically,自动编译
3. ctrl+shift+alt+/ 开启
4. ctrl+f9 使其刷新
5. 修改文件保存后,console就会打出重启的日志
6. 去除不需要重启的文件夹:
spring.devtools.restart.exclude=static/**,public/**
②living reload(浏览器强制刷新)
热部署不会自启动静态资源和视图模板,所以需要living reload
-
The spring-boot-devtools module includes an embedded LiveReload server that can be used to trigger a browser refresh when a resource is changed. LiveReload browser extensions are freely available for Chrome, Firefox and Safari from livereload.com.
springboot开发者工具模块包括一个嵌入式的LivingReload 服务器用于触发浏览器刷新,当资源文件改变的时候。livingReload浏览器扩展对于chrome,firefox和safari是免费的,详见网址:livereload.com
注:启动的时候会发现livingReload的服务端口
-
If you do not want to start the LiveReload server when your application runs, you can set the spring.devtools.liveReload.enabled property to false.
如果你在程序运行的时候不想开启liveReload服务,你可以在配置文件中设置【spring.devtools.livereload.enabled=false】
-
You can only run one LiveReload server at a time. Before starting your application, ensure that no other LiveReload servers are running. If you start multiple applications from your IDE, only the first has LiveReload support.
你只能运行一个liveReload服务器在同一时间,当你启动应用程序的时候,确保没有别的liveReload服务器在运行中,如果你启动了多个应用,只有第一个liveReload服务是有效的。
下一篇 > :springboot项目实战(1)环境准备和服务运行(本地+服务器)
返回目录:springboot系列学习计划