天天看点

开发者工具

        springboot包含了一套额外的工具集,可以让开发的过程更加愉快。spring-boot-devtools模块可以在任何工程中被添加,以支持一些额外的开发时特性。在构建时添加模块的依赖,这样项目就支持了开发者工具集,maven和gradle的示例如下:

<dependencies>

<dependency>

<groupid>org.springframework.boot</groupid>

<artifactid>spring-boot-devtools</artifactid>

<optional>true</optional>

</dependency>

</dependencies>

configurations {

developmentonly

runtimeclasspath {

extendsfrom developmentonly

}

dependencies {

developmentonly("org.springframework.boot:spring-boot-devtools")

注意:         运行一个完全打包的程序时会自动禁用开发者工具,如果你得程序通过java -jar或者通过一个特殊的类加载器启动,则会被认为是一个“生产”程序(会禁用开发者工具集)。如果这个对你不适用(你是通过容器启动的程序),可以考虑排除开发者工具或者设置程序的配置-dspring.devtools.restart.enabled=false。 提示:         在maven中标记依赖为可选或者在gradle中设置自定义属性“仅开发”(如上所示),可以很好的避免过度的在你得项目其他模块应用开发工具。         默认情况,打包的文件中不包含开发工具,如果想远程的使用一些开发工具的功能,可以在构建属性值时禁用excludedevtools来包含开发工具,这个属性maven和gradle都支持。

20.1 属性默认值

        springboot支持一些库使用缓存来提高性能。例如模板引擎可以缓存已编译的模板,避免对模板的反复解析。springmvc还可以将http的头文件添加到缓存中,这样当访问静态资源时可以快速响应。

        虽然缓存在生产环境效果显著,但是在开发时可能产生相反的效果,当你对程序进行更改后缓存机制会导致不会及时的刷新更改。由于这个的原因,springboot开发工具会默认的禁用缓存。

        通常来说,缓存选项的设置在你的application.properties文件中,开发者工具会自动得配置最优得开发时选项,而不是需要你手动得去设置。

        由于在开发springmvc或spring webflux程序时,我们需要看到更多得web请求信息,所以开发者工具会开启web日志组得调试日志功能。这个功能可以让你看到包括请求信息、正在处理请求得程序以及相应结果等信息。如果你需要对所有的信息(包括一些敏感得信息)记录日志,可以将spring.http.log-request-details属性打开。

        如果你不想要自动的应用默认配置,可以将application.properties文件中的spring.devtools.addproperties属性设为false。

20.2 自动重启

        开发者工具会在任意在类路径内的文件有变化时自动重启系统,这个功能在使用ide工具时非常有用,因为它可以快速的反馈代码更改带来的变化。默认情况下,任何指向类路径的文件都会被监控是否更改。另外注意有些资源的更改不需要重启程序,例如静态资源和试图模板。

引发重启:         因为开发者监视器监视的是类路径下的资源,所以唯一会引起重启的是更新了类路径(下的内容)。如何更新类路径取决于你使用的是什么ide工具,例如,eclipse在保存文件更改的时候会触发,而idea在构建项目时(build -> build project)也会触发更改。         由于开发者工具需要一个独立的类加载器才能正确运行,所以只要分支是开启的,你同样可以通过受支持的插件(maven或gradle)来启动程序。当gradle或maven检测到类路径下含有开发工具,就会默认这样做。         自动重启和热加载一起使用往往有更好的效果,具体的细节看“热加载”部分。如果使用了jrebel,为了支持动态类加载会关闭自动重启功能,其他的开发工具功能(如热加载、属性覆盖等)依然可以使用。         在重启期间开发工具依赖应用上下文的关机钩子(shutdown hook)来关闭程序,如果关闭了关机钩子,则开发工具可能不会正确的进行重启。(springapplication.setregistershutdownhook(false))         判断任何一个实体内容发生改变时是否需要重启,开发工具会忽略含有spring-boot、spring-boot-devtools、spring-boot-autoconfigure、spring-boot-actuator以及spring-boot-starter名字的文件。         开发工具需要定制applicationcontext上的resourceloader。如果程序已经提供了一个applicationcontext,开发工具会覆盖applicationcontext,而不会直接重写applicationcontext上的getresource方法。 “重启”或是“重载”         spring boot通过两个类加载器来提供“重启”的技术。不会更改的类(例如第三方jar包里的类)会被加载进一个“基础类加载器”,而你正在开发中的类会被加载进一个“重启类加载器”。当应用重启时,(正在使用的)“重启类加载器”会被废弃掉,一个新的(重启类加载器)将会被创建。由于“基础类加载器”已经是可用状态,这意味着程序使用这种方式会比“冷启动”方式更快的重启。         如果你发现“重启”的速度不能够满足程序的需求,或者遇到了类加载问题,可以尝试使用zeroturnaround公司的jrebel的“重载”技术。这个插件通过重写class文件来快速的重载项目。

        默认情况下,每次程序重启时,都有一个条件评估增量的报告被记录。这份报告显示了你更改的自动配置项如增添/删减的bean,以及设置的配置属性。

        如果想禁用记录报告的功能,设置属性如下:

        某些资源的改变没有必要触发重启机制,例如thymeleaf模板的就地编辑等。默认情况下,位于/meta-inf/maven、/meta-inf/resources、/resources、/static、/public和/templates下的文件发生的更改并不会触发重启机制,不过会触发重载(live reload)事件。如果你想自定义这些排除项,可以配置spring.devtools.restart.exclude属性。例如只想排除/static和/public文件夹,可以设置如下:

        如果你想在保留这些默认配置的情况下添加额外的排除项,可以在spring.devtools.restart.additional-exclude属性代替上面的配置。

        如果你想让“重启”机制监视一个不在类路径下的文件,即当其改变内容时触发重启,可以通过设置spring.devtools.restart.additional-paths属性来实现额外的监视路径。你可以通过上面提到的spring.devtools.restart.exclude属性来控制额外路径下文件内容改变时是进行重启还是重载。

        如果你不想使用重启功能,可以通过spring.devtools.restart.enabled属性禁用它。你可以在application.properties文件中设置这些属性(设置后仍会初始化“重启类加载器”,只是不会监控文件的改变了)。

        如果你想完全的禁用重启功能(例如因为重启功能和某些类库不能一起工作),可以在调用springapplication.run(…)方法之前设置spring.devtools.restart.enabled system属性值为false,示例如下:

public static void main(string[] args) {

system.setproperty("spring.devtools.restart.enabled", "false");

springapplication.run(myapp.class, args);

        当你使用ide工具不断地重新编译更改的文件时,你可能更想要在特殊的时间触发重启。为了达到这种效果,你可以使用一个“触发文件”,只有当触发文件法生更改时,才会实际的触发重启机制。修改文件只会触发检查,而只有devtools认为必要的时候才会进行重启。触发文件的可以手工修改或是通过ide插件进行修改。

        通过在spring.devtools.restart.trigger-file属性中设置你的触发文件路径,来使用“触发文件”。

        你可能会希望将spring.devtools.restart.trigger-file属性设置为全局属性,这样保证所有的项目保持行为的一致。

        在上面的“重启或重载”部分提到了,“重启”是通过两个类加载器实现的。大部分项目中,这种方式可以很好的工作,然而有时也会导致类加载异常。

        默认情况下,所有在ide中打开的项目都是通过“重启类加载器”加载的,而所有不变的.jar文件都是通过“基础类加载器”进行加载的。当你正在开发一个多模块的应用时,不是每个模块都会导入进ide中,这时候你需要自定义一些属性。可以通过创建一个meta-inf/spring-devtools.properties文件来实现自定义。

        spring-devtools.properties文件包含了前缀为restart.exclude和restart.include的属性,include属性中的项目是应该放进“重启类加载器”中的,而exclude中的项目是应该放进“基础类加载器”中的。这个属性的值应该是一个类路径的正则表达,示例如下:

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

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

        所有属性的关键字必须是唯一的,只要属性前缀是restart.include.或restart.exclude.就会被认为是自定义项。         所有来自类路径下的meta-inf/spring-devtools.properties文件都会被加载,你可以在项目内部中或者项目使用的库中打包文件。(这句没看懂)

        当使用标准objectinputstream流反序列化的对象时,重启机制不会正常的工作。可以使用spring的configurableobjectinputstream和thread.currentthread().getcontextclassloader()的结合来进行数据的反序列化。

        不幸的是,有些第三方类库反序列化时没考虑到使用context classloader,如果你发现了这样的问题,你需要和类库的作者联系修复。

20.3 livereload

        spring-boot-devtools包含了一个嵌入式的livereload服务器,它可以在资源修改时触发浏览器的刷新。可以在livereload.com中找到chrome、firefox和safari免费的livereload插件。

        如果你不想使用livereload服务,可以设置spring.devtools.livereload.enabled属性为false。

        在同一时间只能使用一个livereload服务,在开启你得程序之前确保没有其他的livereload服务正在运行。如果你通过ide工具打开了多个项目,只有第一个项目支持livereload服务。

20.4 全局设置

        你可以通过向$home文件夹添加名为.spring-boot-devtools.properties的文件来配置全局devtools设置(请注意,文件名以“.”开头)。 添加到此文件的任何属性将适用于你的计算机上使用devtools的所有 spring boot应用程序。 例如,要配置重启始终使用触发器文件 ,你可以在~/.spring-boot-devtools.properties中添加以下内容:

        在.spring-boot-devtools.properties文件中激活的属性不会影响profile-specific configuration files的加载。

20.5 远程应用

        spring boot的开发者工具并不限制于本地开发,在运行远程程序时也可以使用一些功能。远程支持是可选择的,想开启支持,首先你要确认devtools包含在重打包的文档中,如下;

<build>

<plugins>

<plugin>

<artifactid>spring-boot-maven-plugin</artifactid>

<configuration>

<excludedevtools>false</excludedevtools>

</configuration>

</plugin>

</plugins>

</build>

        然后如下的配置spring.devtools.remote.secret属性:

警告:         在一个远程的应用中启动spring-boot-devtools是存在安全风险的,不要再生产环境中启动该支持。

        远程devtools支持包括两部分:1.接受连接的服务端;2.在ide中运行的客户端。服务端在设置spring.devtools.remote.secret后自动开启,客户端则必须手动开启。

        远程客户端程序是为了在ide中运行而设计的,你需要使用与你连接的远程项目相同的类路径来运行org.springframework.boot.devtools.remotespringapplication。这个程序需要的唯一的参数就是它连接的url。

        例如,当你使用eclipse或sts时,有一个在cloud foundry上的my-app项目,按下面的步骤操作:

在run菜单中选择run configurations… 

创建一个新的java项目“launch configuration”

浏览my-app项目

把org.springframework.boot.devtools.remotespringapplication当成main类

添加https://myapp.cfapps.io到程序参数中(或者你得远程url)

        正在运行的远程客户端可能像下面这样:

. ____ _ __ _ _

/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \

( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \

\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )

' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /

=========|_|==============|___/===================================/_/_/_/

:: spring boot remote :: 2.1.5.release

2015-06-10 18:25:06.632 info 14938 --- [ main] o.s.b.devtools.remotespringapplication :

starting remotespringapplication on pwmbp with pid 14938 (/users/pwebb/projects/spring-boot/code/

spring-boot-devtools/target/classes started by pwebb in /users/pwebb/projects/spring-boot/code/spring-

boot-samples/spring-boot-sample-devtools)

2015-06-10 18:25:06.671 info 14938 --- [ main] s.c.a.annotationconfigapplicationcontext :

refreshing org.springframework.context.annotation.annotationconfigapplicationcontext@2a17b7b6: startup

date [wed jun 10 18:25:06 pdt 2015]; root of context hierarchy

2015-06-10 18:25:07.043 warn 14938 --- [ main] o.s.b.d.r.c.remoteclientconfiguration : the

connection to http://localhost:8080 is insecure. you should use a url starting with 'https://'.

2015-06-10 18:25:07.074 info 14938 --- [ main] o.s.b.d.a.optionallivereloadserver :

livereload server is running on port 35729

2015-06-10 18:25:07.130 info 14938 --- [ main] o.s.b.devtools.remotespringapplication :

started remotespringapplication in 0.74 seconds (jvm running for 1.105)

        因为远程客户端使用了和真是项目相同的路径,所以可以直接读取项目的配置。这是spring.devtools.remote.secret属性如何被读取以及如何通过服务器验证的原因。         通常建议使用https://协议进行连接,这样就可以对通信进行加密,密码也不会被拦截。         如果你需要通过代理访问远程项目,需要对spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port属性进行配置。

        远程客户端通过和本地“重启”机制相同的方式监视类路径文件的变化。任何更新后的文件会被push进远程应用并且触发重启(如果需要的话)。如果你使用本地应用没有的云服务特性来更新迭代,这将非常有用。通常来说,远程更新和重启比完整的构建部署的周期快很多。

        文件只在远程客户端开启的时候会被监控,如果你在远程客户端启动之前改变文件,则更新不会推送到远程服务器上。