重新加载/刷新Spring配置文件而不重新启动servlet容器

时间:2009-02-10 20:23:03

标签: spring

如何在不重新启动servlet容器的情况下刷新Spring配置文件?

我正在寻找除JRebel以外的解决方案。

4 个答案:

答案 0 :(得分:11)

嗯,在测试你的应用程序时执行这样的上下文重新加载会很有用。

您可以尝试其中一个refresh类的AbstractRefreshableApplicationContext方法:它不会刷新以前的实例化bean,但下一次调用上下文将返回刷新的bean。

import java.io.File;
import java.io.IOException;

import org.apache.commons.io.FileUtils;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class ReloadSpringContext {

    final static String header = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
        "<!DOCTYPE beans PUBLIC \"-//SPRING//DTD BEAN//EN\"\n" +
        " \t\"http://www.springframework.org/dtd/spring-beans.dtd\">\n";

    final static String contextA =
        "<beans><bean id=\"test\" class=\"java.lang.String\">\n" +
            "\t\t<constructor-arg value=\"fromContextA\"/>\n" +
        "</bean></beans>";

    final static String contextB =
        "<beans><bean id=\"test\" class=\"java.lang.String\">\n" +
            "\t\t<constructor-arg value=\"fromContextB\"/>\n" +
        "</bean></beans>";

    public static void main(String[] args) throws IOException {
        //create a single context file
        final File contextFile = File.createTempFile("testSpringContext", ".xml");

        //write the first context into it
        FileUtils.writeStringToFile(contextFile, header + contextA);

        //create a spring context
        FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext(
            new String[]{contextFile.getPath()}
        );

        //echo the bean 'test' on stdout
        System.out.println(context.getBean("test"));

        //write the second context into it
        FileUtils.writeStringToFile(contextFile, header + contextB);

        //refresh the context
        context.refresh();

        //echo the bean 'test' on stdout
        System.out.println(context.getBean("test"));
    }

}

你得到这个结果

fromContextA
fromContextB

实现这一目标的另一种方法(也许是更简单的方法)是使用Spring 2.5+的Refreshable Bean功能 使用动态语言(groovy等)和spring,您甚至可以更改bean的行为。请查看spring reference for dynamic language

  

24.3.1.2。可刷豆子

     

其中一个(如果不是)最多   引人注目的价值增加了​​动态   春天的语言支持就是   '可刷新的豆'功能。

     

可刷新的豆子是   带有动态语言支持的bean   少量配置,a   动态语言支持的bean可以   监控其底层的变化   源文件资源,然后重新加载   本身就是动态语言   源文件已更改(例如   当开发人员编辑和保存时   更改了文件   文件系统)。

答案 1 :(得分:8)

对于那些最近绊脚石的人来说 - 解决这个问题的当前和现代方法是使用Spring Boot's Cloud Config

只需在可刷新的bean上添加@RefreshScope注释,在主/配置上添加@EnableConfigServer

所以,例如,这个Controller类:

@RefreshScope
@RestController
class MessageRestController {

    @Value("${message}")
    private String message;

    @RequestMapping("/message")
    String getMessage() {
        return this.message;
    }
}

每当您的配置更新时,都会为message端点返回/message字符串属性的新值。

有关更多实施细节,请参阅官方Spring Guide for Centralized Configuration示例。

答案 2 :(得分:7)

我不建议你这样做。 对于配置修改的单例bean,你期望发生什么?你期望所有单身人士重新加载吗?但是有些对象可能会引用那些单身人士。

同时查看此帖子Automatic configuration reinitialization in Spring

答案 3 :(得分:2)

您可以查看此http://www.wuenschenswert.net/wunschdenken/archives/138,一旦您更改属性文件中的任何内容并保存它,将使用新值重新加载bean。