我正在使用带有maven的SpringBoot 1.3.5。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
和devtools
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
我正在使用2014年之前的Intellij IDEA 2016.2同样的问题。
我正在从Intellij Idea运行我的springboot应用程序,首先启动一切都很好并且可以工作,我可以访问我的静态页面和我的2个Rest Controller工作。
2016-08-18 15:27:58.771 INFO 26626 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@469d0c02: startup date [Thu Aug 18 15:27:57 CEST 2016]; root of context hierarchy
2016-08-18 15:27:58.789 INFO 26626 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/authentication/introspect],methods=[GET]}" onto public com.myapp.models.TokenIntrospection com.myapp.resources.AuthenticationResources.introspectToken(java.lang.String)
2016-08-18 15:27:58.790 INFO 26626 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/configuration],methods=[GET]}" onto public com.myapp.models.AppConfiguration com.myapp.resources.ConfigurationResources.getConfiguration()
2016-08-18 15:27:58.792 INFO 26626 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-08-18 15:27:58.793 INFO 26626 --- [ restartedMain] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
因为简单的“Make Project”不能很好地用于静态重载,我使用“Rebuild Project”,有时候,当app重启时,我没有映射我的控制器,有时会丢失一个,有时两个都丢失了。
我对此没有任何线索:(
修改
@Morfic解决方案不起作用,因此我使用Intellij本地服务器来提供静态内容和gulp-livereload而不是spring-dev-tools。
当我处于开发模式时,我只需要在JS中管理REST调用,因为REST资源在localhost:8080上,但是我在localhost上的静态:63342,并在我的springboot中启用CORS(在属性文件中使用标志启用CORS与否)。
@Configuration
public class CorsConfig extends WebMvcConfigurerAdapter {
@Value("${cors.enabled}")
private boolean corsEnabled;
@Override
public void addCorsMappings(CorsRegistry registry) {
super.addCorsMappings(registry);
if(corsEnabled) {
registry.addMapping("/**")
.allowedOrigins("*")
.allowedMethods("GET", "PUT", "POST", "DELETE", "OPTIONS")
.allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept", "Authorization")
.allowCredentials(true)
.maxAge(3600L);
}
}
}
所以问题仍然悬而未决。
答案 0 :(得分:7)
我只是设法用一个简单的hello-world服务重复这个并使用Rebuild project
几次,因为它只会偶尔复制一次。我的预感是开发工具找出了在IJ有机会完全清理之前发生的变化。重建。可能一旦资源被发布,并且在从我看到的输出目录编译类之前,dev-tools开始重新加载尚未出现的类 ...
在这个假设之后,我查看了日志和类时间戳,并且dev-tools开始重新加载上下文的时间与我的类写入磁盘的时间之间存在大约1s的差距。显然我的@PostConstruct
日志都没有出现,而且spring的autoconfig找不到我的课程......
作为解决方法,您可以使用trigger-file。根据链接或application.properties
文件中的建议,将其添加为home-dir中的全局配置。此外,由于对此文件的任何更改(创建,删除,修改)都会触发重新启动,并且Rebuild project
清除输出目录,因此您必须定义一个额外的路径来查找此文件。因此,假设我们有一个常规的IJ spring boot运行配置,application.properties
中有以下2个:
# name of the file to trigger a restart
spring.devtools.restart.trigger-file=restarttrigger
# where else to look for it. Also . evaluates to the app's base dir
spring.devtools.restart.additional-paths=.
...一旦你看到IJ完成构建过程,转到app root dir并添加或删除你的触发器文件,具体取决于它是否已经存在,这将导致重启。我已经测试了几次,没有尝试到目前为止失败。下面是手动重启过程的简短视频演示:
有几种方法可以自动执行此过程。除了在IJ中定义一个人工制品并使用后期处理ant任务来生成文件之外,你可以使用maven(你已经在使用它)来生成这样一个文件,但缺点是你必须使用{{1}而不是maven compile
,因为IJ在进行重建时不会调用maven(或者我还没有发现如何做到这一点)。请在下面找到一个简单的配置based on the fact that:
(注意:在Maven 2.0.5及更高版本中,绑定到阶段的多个目标的执行顺序与它们在POM中声明的顺序相同,但不支持同一插件的多个实例。插件被分组以一起执行并在Maven 2.0.11及更高版本中进行排序。
因此,the compiler plugin is by default bound to the compile
phase,我们添加了一个小任务,使用Rebuild project
文件(或其他任何内容)生成trigger-file
application.properties
进一步更新:
查看FileSystemWatcher.scan()
的来源,有一个<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<!-- first, compile all we need -->
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
</plugin>
<plugin>
<!-- then, generate the trigger-file so dev-tools will restart -->
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<copy file="${project.basedir}/src/main/resources/application.properties"
toFile="${project.basedir}/restarttrigger" overwrite="true" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
循环,可以解释为:,而自上次检查后文件系统上仍有变化,等待(可配置的时间并再次验证
do-while
根据documentation,private void scan() throws InterruptedException {
Thread.sleep(this.pollInterval - this.quietPeriod);
Map<File, FolderSnapshot> previous;
Map<File, FolderSnapshot> current = this.folders;
do {
previous = current;
current = getCurrentSnapshots();
Thread.sleep(this.quietPeriod);
}
while (isDifferent(previous, current));
if (isDifferent(this.folders, current)) {
updateSnapshots(current.values());
}
}
可以通过quietPeriod
属性配置,但根据上面提到的来源,它必须是小于spring.devtools.restart.quiet-period
的值可通过pollInterval
配置。因此,玩弄设置,我得到了一个不错的结果:
spring.devtools.restart.poll-interval
最后,您应该能够将这些值调整到最适合您的值。
尽管如此,如果您要修改的源是静态资源(如FE GUI页面)并且根据您的要求,可能最好使用从其位置为其提供服务的工具,例如节点或类似的简单http服务器。 ..
答案 1 :(得分:0)
@ Morfic的这部分答案对我很有帮助:
# Amount of time (in milliseconds) to wait between polling for classpath changes.
spring.devtools.restart.poll-interval=3000
# Amount of quiet time (in milliseconds) required without any classpath changes before a restart is triggered.
spring.devtools.restart.quiet-period=2999