Перезагрузка/обновление Spring файла конфигурации без перезапуска контейнера сервлета

Как обновить конфигурационный файл Spring без перезагрузки контейнера сервлета?

Я ищу решение, отличное от JRebel.

Ответ 1

Ну, может быть полезно выполнить такую ​​перезагрузку контекста при тестировании вашего приложения.

Вы можете попробовать метод refresh одного из классов AbstractRefreshableApplicationContext: он не обновит ваш ранее установленный beans, но следующий вызов контекста вернет обновленный beans.

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

Еще один способ достичь этого (и, возможно, более простой) - использовать функцию Refreshable Bean Spring 2.5+ С динамическим языком (groovy и т.д.) И Spring вы даже можете изменить поведение Bean. Посмотрите на ссылку spring для динамического языка:

24.3.1.2. Обновляемый beans

Один из (если не самый) неотразимые добавочные значения динамических поддержка языка в Spring является 'refreshable bean'.

Обновляемый Bean является с поддержкой динамического языка Bean, что с небольшая конфигурация, с поддержкой динамического языка Beanотслеживать изменения в исходный файловый ресурс, а затем перезагрузить когда динамический язык исходный файл изменяется (например, когда разработчик редактирует и сохраняет изменения в файле на Файловая система).

Ответ 2

Для тех, кто спотыкается об этом совсем недавно, современный и современный способ решения этой проблемы - использовать Spring Boot Cloud Config.

Просто добавьте @RefreshScope аннотацию к обновляемым компонентам и @EnableConfigServer в свою основную/конфигурацию.

Так, например, этот класс Controller:

@RefreshScope
@RestController
class MessageRestController {

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

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

Возвращает новое значение вашего свойства message String для конечной точки /message, когда refresh вызывается в Spring Boot Actuator (через конечную точку HTTP или JMX).

См. официальный пример Spring Guide for Centralized Configuration для получения дополнительной информации о реализации.

Ответ 3

Я бы не рекомендовал вам это делать. Что вы ожидаете от синглтона beans, который изменила их конфигурация? вы ожидаете перезагрузки всех синглтонов? но некоторые объекты могут содержать ссылки на эти синглтоны.

См. этот пост, а также Автоматическая повторная инициализация конфигурации в Spring

Ответ 4

Вы можете посмотреть http://www.wuenschenswert.net/wunschdenken/archives/138, где, как только вы измените какую-либо вещь в файле свойств и сохраните ее, beans будет перезагружать новыми значениями.