Java classes as configuration files in a JEE applicaton


I like the idea of using normal Java classes as configuration files, rather than xml, because they allow us to keep the class and reference type, that makes it easier to refactor classes and keep things in place.

However this sometimes is not always possible with the way statics works in Java.

Take this simple code sample:

    class Config {
        static {
            AuthPlugin.addRule("admin", "AdminController");
        }
    }

    class AuthPlugin {
        static final Map<String, String> roleRules = new HashMap<String, String>();

        static String addRule(String role, String controllerClass) {
            roleRules.put(role, controllerClass); return role;
        }       
       
        static int size() {
            return roleRules.size();
        }
    }

Here we are configuring the AuthPlugin by calling AuthPlugin.addRule(...) to add a controller rule to the role admin.

The problem is that the configuration stuff will never be invoked unless we somewhere in the application refer to the Config class, which we might not always wish to do.

A call from anywhere in our application to AuthPlugin.size() will return zero. 

---------------------------
However if we were to annotate the Config.java class with an annotation that will initialize the config class and run it before the AuthPlugin is used then we are golden.

For instance the Spring component annotation @Component does this for us, and all static invocations will be executed and we can now utilize it as a real config class.

   @Component
    class Config {
        static {
            AuthPlugin.addRule("admin", "AdminController");
        }
    }

Calling AuthPlugin.size() now after server has started up, will return 1.

Same thing would apply to instances as well:

   @Component
    static class Config {
        static String ADMIN = AuthPlugin.addRule("admin", "AdminController");
    }

Of course, this depends very much on the order things are scanned or loaded by Spring, but this is true for any configuration really that depend on another.
We can define the order things are scanned in our xml configuration of Spring.


2 comments:

  1. Will it be possible to change config and get recompiled on the fly without redeploying?

    ReplyDelete
  2. Unfortunately no, statics in Java will always be invoked once. Having an XML file behaves the same way if your xml is adding things to for instance an ArrayList. If you change your XML your current running deployment have already added that to the arraylist, so removing that block from the XML won't help you get rid of that instance, and here it is the same thing.

    It is a for configuration during startup.

    Spring also have the Bootstrap like mechanism:

    http://mseifed.blogspot.se/2012/10/bootstrap-with-spring-mvc.html

    But not suitable for configuration since everything happens in a method rather than on the class level. The class level allows us to access the configured properties like I have shown in the last example.

    ReplyDelete