Results 1 to 6 of 6

Thread: Overriding Module's configuration

  1. #1

    Default Overriding Module's configuration

    Hi,

    I am developing a module that can be included by clients to add functionality to their application. This module is to be distributed as a jar file. Inside the jar I am placing the standard configuration for my beans (i.e. a 'module-context.xml' file) and all the required files to make it work.

    As such, my beans are already (and correctly) wired in the module-context.xml file. Still I would like to allow a developer that uses my module to change certain bean wirings.

    For instance: Imagine that my module has three Beans wired by default; BeanA, BeanA1 and BeanA2. BeanA is wired with BeanA and BeanB, according to the module-context.xml file.

    A client of mine wants to create his own version of BeanA2 and discard the one the module ships with. Is there any way the user can configure in his XML config file the new BeanA2 and wire it up my already configured BeanA ?

    packaged with my .jar file is the module-context.xml file :
    HTML Code:
    ...
    <bean id="BeanA" class="...">
       <property name="beanA1" ref="BeanA1" />
       <property name="beanA2"  ref="BeanA2" />
    </bean>
    
    <!-- BeanA1 and BeanA2 are configured here as well-->
    ...
    and I would like the user of the module to be able to do something like this (of course this syntax is invalid):

    HTML Code:
    ...
    <bean id="CustomBeanA2" class="...">
    
    </bean>
    
    //inject CustomBeanA2 into BeanA
    <bean overrides="BeanA">
       <property name="BeanA2" ref="CustomBeanA2" />
    </bean>
    ...

    In this way the user of the module does not have to configure every object in my beans file again. (I actually have lots of beans configured by default)

    (Note: I would like to avoid strange "hacks" if possible, like creating a method named setUserCustomBeanA2 in BeanA and then autowiring byName. Inside that method checking if the instance var has already a value and if it does overwriting. I should also do something similar in the setBeanA2 method, since I have no guarantee of which setter method will be executed first)

    Please let me know if I was not clear enough.

    Regards
    AB
    Regards
    Andres B.

  2. #2
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    If you have two applicationContext files each containing the same named bean e.g. bean="sameBeanName" the last one loaded should win. I'm not sure if you'd consider this a hack or not.

  3. #3

    Default

    Quote Originally Posted by karldmoore View Post
    If you have two applicationContext files each containing the same named bean e.g. bean="sameBeanName" the last one loaded should win. I'm not sure if you'd consider this a hack or not.
    I don't, as long as it is clear how to set order on the config files (i.e. documented)

    Also I'm not sure I understand how this fixes my issue.. unless I set all beans to lazy-init ¿? I mean.. I need both BeanA2 and CustomBeanA2 "loaded" (in that order) before BeanA is loaded so Spring wires the correct bean.

    Is there any way to specify that?

    Thanks for your response
    regards
    Andres B.

  4. #4
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Give this example a try. You can comment out one of the various beans in the context and see what it does. Doesn't this solve your problem?

    BeanOverrideExample.java
    Code:
    package example;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    public class BeanOverrideExample
    {
    	public static void main ( String [] args )
    	{
    		ApplicationContext applicationContext = new ClassPathXmlApplicationContext ( new String [] { "applicationContextOne.xml", "applicationContextTwo.xml" } );
    		SimpleBean simpleBean = ( SimpleBean ) applicationContext.getBean ( "simpleBean" );
    		simpleBean.sayHello ();
    	}
    }
    SimpleBean.java
    Code:
    package example;
    
    public class SimpleBean
    {
    	private String someOtherProperty;
    	private AnotherSimpleBean anotherSimpleBean;
    	
    	public void setSomeOtherProperty ( String someOtherProperty ) 
    	{
    		this.someOtherProperty = someOtherProperty;
    	}
    	
    	public void setAnotherSimpleBean ( AnotherSimpleBean anotherSimpleBean )
    	{
    		this.anotherSimpleBean = anotherSimpleBean;
    	}
    	
    	public void sayHello ()
    	{
    		System.out.println ( "Hello World! " + someOtherProperty );
    		anotherSimpleBean.sayHelloAlso ();
    	}
    }
    AnotherSimpleBean.java
    Code:
    package example;
    
    interface AnotherSimpleBean
    {
    	void sayHelloAlso ();
    }
    AnotherSimpleBeanOne.java
    Code:
    package example;
    
    public class AnotherSimpleBeanOne implements AnotherSimpleBean
    {
    	public void sayHelloAlso ()
    	{
    		System.out.println ( "Hello World from another simple bean one" );
    	}
    }
    AnotherSimpleBeanTwo.java
    Code:
    package example;
    
    public class AnotherSimpleBeanTwo implements AnotherSimpleBean
    {
    	public void sayHelloAlso ()
    	{
    		System.out.println ( "Hello World from another simple bean two" );
    	}
    }
    applicationContextOne.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
           
           <bean id="anotherSimpleBean" class="example.AnotherSimpleBeanOne"/>
           
           <bean id="simpleBean" class="example.SimpleBean">
           		<property name="someOtherProperty" value="applicatioContextOne.xml set this"/>
       			<property name="anotherSimpleBean" ref="anotherSimpleBean"/>
           </bean>       
    </beans>
    applicationContextTwo.xml
    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    
    <beans xmlns="http://www.springframework.org/schema/beans"
    	   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
           
           <bean id="anotherSimpleBean" class="example.AnotherSimpleBeanTwo"/>
           
           <!--
           <bean id="simpleBean" class="example.SimpleBean">
       			<property name="someOtherProperty" value="applicatioContextTwo.xml set this"/>
       			<property name="anotherSimpleBean" ref="anotherSimpleBean"/>
           </bean>  
           -->
                
    </beans>

  5. #5

    Default

    Yeah, it indeed solves my problem! that is something I didn't imagine it could happen. Really cool!

    I didn't know it would replace the AnotherSimpleBeanTwo in SimpleBean; but hey! who am I to judge!

    Do you happen to know if the order of the config files specified in a web.xml (by using the corresponding spring property) is preserved?

    Very useful,
    Thanks
    Andres B.

  6. #6
    Join Date
    Sep 2006
    Location
    UK
    Posts
    8,424

    Default

    Quote Originally Posted by sotretus View Post
    Yeah, it indeed solves my problem! that is something I didn't imagine it could happen. Really cool!

    I didn't know it would replace the AnotherSimpleBeanTwo in SimpleBean; but hey! who am I to judge!
    I thought it might be that simple, it's always nice when it is! Glad it was useful.

    Quote Originally Posted by sotretus View Post
    Do you happen to know if the order of the config files specified in a web.xml (by using the corresponding spring property) is preserved?
    I think the order is preserved so the last one loaded wins, if that makes sense.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •