Springboot – DevTools – 在重建项目时并不总是映射RestController

前端之家收集整理的这篇文章主要介绍了Springboot – DevTools – 在重建项目时并不总是映射RestController前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

我正在使用带有maven的SpringBoot 1.3.5.

和devtools

我正在使用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

因为简单的“Make Project”不能很好地用于静态重载,所以我使用“Rebuild Project”,有时,当app重启时,我没有映射我的控制器,有时一个丢失,有时两个都丢失了.

我对此没有任何线索:(

编辑

@Morfic解决方案不起作用,因此我使用Intellij本地服务器来提供静态内容和gulp-livereload而不是spring-dev-tools.

IJ local server

当我处于开发模式时,我只需要在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);
        }
    }
}

所以仍有待解决问题的问题.

最佳答案
我只是设法用一个简单的hello-world服务重复这个,并使用Rebuild项目几次,因为它只会偶尔复制一次.我的预感是,开发工具在IJ有机会完全清理之前发现了一个变化.重建.可能一旦资源被发布,并且在从我看到的输出目录编译类之前,dev-tools开始重新加载尚未出现的类…

在这个假设之后,我查看了日志和类时间戳,并且dev-tools开始重新加载上下文的时间与我的类写入磁盘的时间之间存在大约1s的差距.显然我的@PostConstruct日志都没有出现,而且spring的autoconfig找不到我的类……

作为解决方法,您可以使用trigger-file.根据链接或application.properties文件中的建议,将其添加为home-dir中的全局配置.此外,由于对此文件的任何更改(创建,删除,修改)都会触发重新启动,并且Rebuild项目会清除输出目录,因此您必须定义一个额外的路径来查找此文件.因此,假设我们有一个常规的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 - boot dev tools manual restart

有几种方法可以自动执行此过程.除了在IJ中定义一个人工制品并使用后期处理ant任务生成文件之外,你可以使用maven(你已经使用过)生成这样一个文件,但缺点是你必须使用maven编译而不是重建项目是因为IJ在进行重建时不会调用maven(或者我还没有发现如何做到这一点).请在下面找到一个简单的配置based on the fact that

(Note: In Maven 2.0.5 and above,multiple goals bound to a phase are executed in the same order as they are declared in the POM,however multiple instances of the same plugin are not supported. Multiple instances of the same plugin are grouped to execute together and ordered in Maven 2.0.11 and above).

因此,the compiler plugin is by default bound to the compile phase,所以我们使用application.properties文件(或其他任何东西)添加一个小任务来生成trigger-file

进一步更新:

查看FileSystemWatcher.scan()的源代码,有一个do-while循环可以解释为:虽然自上次检查后文件系统仍在进行更改,但等待(可配置)时间并再次验证

private void scan() throws InterruptedException {
    Thread.sleep(this.pollInterval - this.quietPeriod);
    MapIoUs;
    MapIoUs = current;
        current = getCurrentSnapshots();
        Thread.sleep(this.quietPeriod);
    }
    while (isDifferent(prevIoUs,current));
    if (isDifferent(this.folders,current)) {
        updateSnapshots(current.values());
    }
}

根据documentation,quietPeriod可以通过spring.devtools.restart.quiet-period属性进行配置,但是根据上面提到的源,它必须是一个小于pollInterval的值,可以通过spring.devtools.restart.poll-interval配置.因此,玩弄设置,我得到了一个不错的结果:

# 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

最后,您应该能够将这些值调整为最适合您的值.

尽管如此,如果您正在修改的源是静态资源,例如FE GUI页面,并且根据您的要求,也许最好使用从其位置为它们提供服务的工具,例如节点或类似的简单http服务器……

猜你在找的Springboot相关文章