Results 1 to 9 of 9

Thread: beanId runtime configuration

  1. #1
    Join Date
    Feb 2007
    Posts
    5

    Default beanId runtime configuration

    Recently I ran into a situation where I need to change the beanId name dynamically during run-time, which means during runtime even the client called a specific bean with defined bean Id name, the spring container can find another beanId during run-time.

    Does anyone have any idea how I can achieve this in Spring?

  2. #2
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    That is not possible, as far as I am aware of. Though, I am wondering why you let a client access a bean like that in the first place?

    Maybe you could describe your use case, so perhaps another solution could be found.

    Regrds,
    Andreas

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

    Default

    Although it's not exactly what you want, you could register an alias at runtime. The bean name would remain the same, but you could allow it to be known as another name at runtime.
    http://www.springframework.org/docs/...a.lang.String)

  4. #4
    Join Date
    Feb 2007
    Posts
    5

    Default

    Quote Originally Posted by Andreas Senft View Post
    That is not possible, as far as I am aware of. Though, I am wondering why you let a client access a bean like that in the first place?

    Maybe you could describe your use case, so perhaps another solution could be found.

    Regrds,
    Andreas
    Thanks a lot Andreas.

    Here's the reason why I need such a solution Actually this kind of solution could be done in some other IOC containers such as Hivemind.

    Currently I have three implmentations of a business logic interface:

    1) remote stateless session bean
    2) local stateless session bean
    3) POJO

    At this point I don't know which one we'll definitely use in the future so ideally we want to keep all of them but have an option to switch on/off anytime between them.

    Right now all of the implementations have been done as Spring services so I am looking from Spring if it is possible that the client call can be maintained the same as before, suppose client.getService("CalculationService") regardless which implementation actually will be invoked.

    I understand spring can provide runtime control in terms of bean's property but in this case I need to be able to change the beanId on the fly.

    In Hivemind what you can do is to have some script language inside the xml to enable certain conditional logic.

    Hopefully this helps.

  5. #5
    Join Date
    Aug 2004
    Posts
    2,715

    Default

    Ok, that makes things clearer.
    If you like to have scripting support, you can have that in Spring, too. See here for reference.

    Another approach I can think of, is having a proxy that knows about the three "real" services and delegates to one of them based on a discriminator. That discriminator could be switched using a static ThreadLocal, for example. A more sophisticated option could be using JMX for configuration.

    Regards,
    Andreas

  6. #6

    Default

    Hello,

    Do you need to switch at runtime ?

    You could have a look at HotSwappableTargetSource.html

    If you don't need to switch at runtime, you could - as karldmoore said - use an alias (the client always looks up the bean by alias) and set the alias for example with a propertyPlaceholder and a system property.

    Something like:
    Code:
    <bean id="defaultPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
    
    <bean id="myService_1" ... />
    <bean id="myService_2" ... />
    <bean id="myService_3" ... />
    
    <alias name="${myService}" alias="myService" />

  7. #7
    Join Date
    Feb 2007
    Posts
    5

    Default

    Quote Originally Posted by pgras View Post
    Hello,

    Do you need to switch at runtime ?

    You could have a look at HotSwappableTargetSource.html

    If you don't need to switch at runtime, you could - as karldmoore said - use an alias (the client always looks up the bean by alias) and set the alias for example with a propertyPlaceholder and a system property.

    Something like:
    Code:
    <bean id="defaultPropertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"/>
    
    <bean id="myService_1" ... />
    <bean id="myService_2" ... />
    <bean id="myService_3" ... />
    
    <alias name="${myService}" alias="myService" />
    This is really helpful. However I don't think I can define things like ${myService} inside <alias tag.

    But if Spring does support it your suggestion is absolutely brilliant.

    I just tried your method anyway but get the following error:

    NoSuchBeanDefinitionException: No Bean Name '${myService}' is defined:

  8. #8

    Default

    You're right, it doesn't work

    This one works (tested)

    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="defaultPropertyConfigurer"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    		lazy-init="false" />
    
    	<bean id="testService_1" class="test.TestServiceImpl_1"
    		scope="singleton" />
    
    	<bean id="testService_2" class="test.TestServiceImpl_2"
    		scope="singleton" />
    
    	<bean id="testService"
    		class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="targetSource" ref="testServiceTargetSource" />
    	</bean>
    	
    	<bean id="testServiceTargetSource"
            class="org.springframework.aop.target.SingletonTargetSource">
            <constructor-arg ref="${testService}" />
        </bean> 
    
    </beans>
    You could even replace SingletonTargetSource with HotSwappableTargetSource to be able to switch at runtime...

    -Patrick

  9. #9
    Join Date
    Feb 2007
    Posts
    5

    Default

    Quote Originally Posted by pgras View Post
    You're right, it doesn't work

    This one works (tested)

    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="defaultPropertyConfigurer"
    		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
    		lazy-init="false" />
    
    	<bean id="testService_1" class="test.TestServiceImpl_1"
    		scope="singleton" />
    
    	<bean id="testService_2" class="test.TestServiceImpl_2"
    		scope="singleton" />
    
    	<bean id="testService"
    		class="org.springframework.aop.framework.ProxyFactoryBean">
    		<property name="targetSource" ref="testServiceTargetSource" />
    	</bean>
    	
    	<bean id="testServiceTargetSource"
            class="org.springframework.aop.target.SingletonTargetSource">
            <constructor-arg ref="${testService}" />
        </bean> 
    
    </beans>
    You could even replace SingletonTargetSource with HotSwappableTargetSource to be able to switch at runtime...

    -Patrick
    Hi Patrick,

    You are the champion. This works exactly what I need.

    What I also discovered is it only works in Spring 2.0. Anyway, do you have any sample code of hotswap as well because not too much info about it from Spring. Even how to use singletonTargetSource was not mentioned too much.

    Thx again for your great help.

Posting Permissions

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