tags:

views:

2022

answers:

2

How can I refresh spring configuration file without restarting my servlet container.

I am looking for a solution other than javarebel.

+2  A: 

I wouldn't recommend you to do that. What do you expect to happen to singleton beans which their configuration modified? do you expect all singletons to reload? but some objects may hold references to that singletons.

See this post as well Automatic configuration reinitialization in Spring

LiorH
A: 

Well, it can be useful do perform such a context reload while testing you're app.

You can try the refresh method of one of the AbstractRefreshableApplicationContext class: it won't refresh your previously instanciated beans, but next call on context will return refreshed 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\"&gt;\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"));
    }

}

And you get this result

fromContextA
fromContextB

Another way to achieve this (and maybe a more simple one) is to use the Refreshable Bean feature of Spring 2.5+ With dynamic language (groovy, etc) and spring you can even change your bean behavior. Have a look to the spring reference for dynamic language:

24.3.1.2. Refreshable beans

One of the (if not the) most compelling value adds of the dynamic language support in Spring is the 'refreshable bean' feature.

A refreshable bean is a dynamic-language-backed bean that with a small amount of configuration, a dynamic-language-backed bean can monitor changes in its underlying source file resource, and then reload itself when the dynamic language source file is changed (for example when a developer edits and saves changes to the file on the filesystem).

Guillaume