有没有在用jetty热部署的时候遇到这个问题

有没有在用jetty热部署的时候遇到这个问题,第1张

通过Gradle我们可以很方便的使用内置jetty启动我们的web程序,在本地进行调试。但是在使用的过程中,我发现了几个问题,导致本地调试的效率大受影响。

如果使用 gradle jettyRun 启动jetty服务器后,项目里的静态资源(jsp,html,JavaScript文件)都被锁定了,导致无法实时修改这些静态资源。

既然无法实时修改这些静态资源,那意味着我们做一个很小的改动都需要先停止jetty server,然后修改,再重新启动jetty server,这样来回浪费很多时间,尤其是涉及前台页面改动时,每调整一个参数都需要重启jetty。

由于我以前使用过Maven,在Maven里jetty是可以显示热部署的。也就是说如果有静态文件被改动,那么jetty可以实时load并展现。那么在Gradle里面实现这个应该也不是难事,花了一些时间搞定了。

首先要解决文件被锁定的问题。

文件被锁定是由于在使用windows系统时,jetty默认在内存中映射了这些文件,而windows会锁定内存映射的文件。解决的办法就是修改jetty的配置,让其在启动server时将useFileMappedBuffer标志位设置为false。

设置方法有两种,一种是修改webdefault.xml文件中的useFileMappdBuffer标志位。webdefault.xml文件是jetty启动服务的配置文件,其先于项目中的WEB-INF/web.xml文件被加载。 jetty包中默认有这个文件,可以将其提取出来,保存在项目根目录下,并修改useFileMappedBuffer节点。

<param-name>useFileMappedBuffer</param-name>

<param-value>false</param-value>

然后在build.gradle加入对此文件的引用。

[jettyRun, jettyRunWar,jettyStop]*.with {

webDefaultXml = file("${rootDir}/webdefault.xml")

}

第二种方法是修改项目中的 WEB-INF/web.xml 文件,在其中加入这个节点。

<servlet>

<!-- Override init parameter to avoid nasty -->

<!-- file locking issue on windows. -->

<servlet-name>default</servlet-name>

<init-param>

<param-name>useFileMappedBuffer</param-name>

<param-value>false</param-value>

</init-param>

</servlet>

解决jetty的hot deploy的问题。

这个就比较简单了,Gradle的jetty插件有两个属性,一个是reload属性,需要设置为automatic。另一个属性是 scanIntervalSeconds,这是指定jetty扫描文件改变的时间间隔,默认为0,单位是秒。 在build.gradle中加入设置。

jettyRun {

reload ="automatic"

scanIntervalSeconds = 1

}

齐活。接下来运行 gradle jettyRun ,待服务启动起来以后,如果修改了静态资源,只需要按 Ctrl + R 刷新页面即可重新加载资源。

今天向大家介绍的是spring-boot,这个java框架在RESTful思想的背景下,也火了一把,而且还可能火下去。因此就研究了一下怎么搞。

实际上过程很简单。关键在于理解概念,以及在哪种情况下,使用哪种工具。如果这个可以在头脑中有一个清晰的逻辑概念,那就一切OK。

1. 先简介一下各种工具框架的作用

首先是Gradle,实际上这个工具在我的其他手记中已经有说道,就是一个自动化建构工具,为了解决依赖问题,同时构建项目和打包部署项目。这样就能拨开面纱,看她的脸了。Maven主要因为xml的繁琐,会被抛弃。但是现在的大多数项目还在使用Maven,因为路径依赖的问题,还是会存在一段时间的。(个人看法)

然后是spring-boot 这个框架,这个框架就需要我们打破web传统,可以没有web.xml,也可以不用装tomcat,所有的内容都在一个jar中就可以完成。只需运行java -jar xxx 就可以完成了。但是不知道效率、性能怎么样? 不过就简单性,是OK的。而且一切又回归到main了,这不也是所有语言的开始吗?

至于,在spring-boot中结合jersey实现RESTful,也只用理解jersey只是一种实现而已,然后在spring-boot中注册一下,就可以了,不过具体细节还有很多,这个要在下一篇具体介绍。

2. 安装,创建项目

首先安利一个网站 start spring-boot,可以在网站上直接定制需要的技术,像AOP,JDBC,MYSQL,AMQP等都可以直接生成。其他步骤如下,首先安装好gradle,注意:配置好环境变量。切换到项目目录后,直接gradle init 即可,然后就是一些约定俗成的文件夹格式。可以自己手动创建好就行了。

3. 常见的一些问题

3.1 编码打包的时候,和jvm的编码

编译的时候在build.gradle 最后面添加一下代码,表示,在complile的时候采用UTF-8编码。

tasks.withType(JavaCompile) {

options.encoding = "UTF-8"

}

使用jvisualvm图形化工具查看spring-boot概况

修改gradle.bat 中的set DEFAULT_JVM_OPTS= 默认为空    修改为set DEFAULT_JVM_OPTS="-Dfile.encoding=UTF-8" 可以在上图中看到JVM参数一栏中这个参数GBK,然后直接修改。

3.2 热部署

spring-boot-devtools  可以参考一下这篇文章:springboot + devtools(热部署)

reload和restart的区别

restart:先stop 再start,服务会停止。如果重启了肯定就会reload的。

reload是只是重新加载文件,但是服务不停。重新加载,就像网页F5一样。

这些细微的区别才是关键。

3.3 debug

怎么实现debug运行

gradle bootRun --debug-jvm

在ide中的话直接右键单击debug运行java Application是不是异常的简单啊。

4. 重要文件分析

build.gradle

buildscript {

ext {

springBootVersion = '1.5.1.RELEASE'

}

repositories {

mavenCentral()

}

dependencies {

classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")

}

}

apply plugin: 'java'

apply plugin: 'eclipse'

apply plugin: 'org.springframework.boot'

jar {

baseName = 'spring-boot'

version = '0.0.1-SNAPSHOT'

}

repositories {

jcenter()

}

dependencies {

compile group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: '1.5.1.RELEASE'

compile group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: '1.5.1.RELEASE'

compile group: 'org.springframework.boot', name: 'spring-boot-devtools', version: '1.5.1.RELEASE'

compile group: 'org.springframework.boot', name: 'spring-boot-starter-jersey', version: '1.5.1.RELEASE'

testImplementation 'junit:junit:4.12'

}

sourceCompatibility = 1.8

targetCompatibility = 1.8

tasks.withType(JavaCompile) {

options.encoding = "UTF-8"

}

这个文件里面包含3块 构建脚本, 包依赖,编译打包。

Application.java 启动

package web

import org.glassfish.jersey.servlet.ServletContainer

import org.glassfish.jersey.servlet.ServletProperties

import org.springframework.boot.SpringApplication

import org.springframework.boot.autoconfigure.SpringBootApplication

import org.springframework.boot.context.properties.EnableConfigurationProperties

import org.springframework.boot.web.servlet.ServletRegistrationBean

import org.springframework.context.annotation.Bean

import org.springframework.context.annotation.ComponentScan

import config.DatabaseProperties

import config.JerseyConfig

import config.RedisProperties

@SpringBootApplication

public class Application {

@Bean

public ServletRegistrationBean jerseyServlet() {

ServletRegistrationBean registration =

new ServletRegistrationBean(new ServletContainer(), "/rest/*")

registration.addInitParameter(

ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName())

return registration

}

public static void main(String[] args) {

SpringApplication.run(Application.class, args)

}

}

中间的一串@Bean在这里可以无视,是注册jersey用的,后面再说。spring-boot在运行的时候会扫描有main方法的类,这里就是Application类,然后运行main方法,这里SpringApplication

Hello.java  访问

package web

import org.springframework.beans.factory.annotation.Autowired

import org.springframework.beans.factory.annotation.Value

import org.springframework.core.env.Environment

import org.springframework.web.bind.annotation.*

import config.RedisProperties

@RestController

public class Hello {

@RequestMapping("/")

public String hello() {

return "hello world"

}

}


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11551953.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-16
下一篇2023-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存