Announcement Announcement Module
Collapse
No announcement yet.
beanId runtime configuration Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • 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
    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

    Comment


    • #3
      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)

      Comment


      • #4
        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.

        Comment


        • #5
          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

          Comment


          • #6
            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" />

            Comment


            • #7
              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:

              Comment


              • #8
                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

                Comment


                • #9
                  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.

                  Comment

                  Working...
                  X