Announcement Announcement Module
Collapse
No announcement yet.
static initialization block Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • static initialization block

    Hello,

    Could someone please point me in a right direction as to how I can use Spring to place the setup that I'm doing in static initialization blocks in my classes in the Spring's application context. Does Spring support this functionality at all? If yes, could you please give me some examples of how this is done, or point me to the place in the docs.

    Here is my situation: I have a class, in static initialization block of which I load some xml files to be used in creation of a per-user session.

    Something like this:

    private static RuleBase ruleBase;
    private static URL ruleFilePath = MY_PATH;
    private WorkingMemory session;

    static {
    loadRules();
    }


    private static void loadRules(){

    try{

    ruleBase = RuleBaseLoader.loadFromUrl(ruleFilePath);

    }catch(){...}
    }


    public void decide(Input fact){
    session = ruleBase.newWorkingMemory();
    session.assertObject(fact);
    session.fireAllRules();
    }

    Loading of these xml files is very time consuming, and I'd like to do it just once per class. Then based on these files, I lazily create a session when it's requested on an individual object of this class's type. I want to externalize the configuration of these xml into the Spring config, so that if it's changed, I don't need to recompile my code.

    For me it's a matter of deciding of whether to use Spring or just go with reading the xml names from a property file, cache them in a map inside the static initializer, and use later.

    Thanks for all the ideas, suggestions and pointers in advance.
    Simeon

  • #2
    You could do it in 2 steps:

    1)give a RuleBase instance to the class with the decide method, and lets call the class: Decide (you have to pay me to make up a better name ).

    Code:
    class Decide{
        private Rulebase _rb;
    
        public Decide(Rulebase rb){_rb = rb;}
    
        public void decide(Input fact){....}
    }
    Now you have refactored the initialisation of the Rulebase outside that object. This was the most imporant step.

    2) create a new object that is responsible for loading the rulebase and creating Decide objects: DecideFactory.

    Code:
    class DecideFactory{
    
          private RuleBase _rb;
          private URL _ruleFilePath;
    
          public DecideFactory(URL ruleFilePath){
                       _ruleFIlePath = ruleFilePath;
          }
    
          public void init(){
               uleBase = RuleBaseLoader.loadFromUrl(_ruleFilePath); 
          }
    
          public Decide create(){
                return new Decide(_rb);
          }
    }
    In some cases it would be better to remove the loading functionality from the DecideFactory and inject an instance of the Rulebase into the DecideFactory. But I don`t know enough about your problem to justify this added complexity. The same goes for the DecideFactory. If you only need a RuleBase reference to create a Decide object, then you could drop the DecideFactory. But sometimes it is clearer if you have a factory instead of a lot of objects that are needed to construct an object. So it depends on your needs what is best. If you decide to drop the DecideFactory you need a RuleBase initialisation object and a BeanFactory would be well suited for this purpose.



    And now you can configure it in Spring:

    Code:
    <bean id="decideFactory" 
              class="DecideFactory"
              init-method="init"/>
         <constructor-arg value="c&#58;\rulebases\foo.rbs"/>
    </bean>
    And if some objects needs a decide instance, you can inject the decideFactory in that object.

    Code:
    <bean id="foo" class="Foo">
          <constructor-arg ref="decideFactory"/>
    </bean>
    This how I personally like to work (I don`t want to retrieve objects directly from the application context).

    Comment

    Working...
    X