How to set dynamically a bean reference in Spring?

后端 未结 6 978
抹茶落季
抹茶落季 2020-12-09 19:56
   
     



  

        
相关标签:
6条回答
  • 2020-12-09 20:11

    You can do it using PropertyPlaceholderConfigurer or using @Profile

    Also See

    • is-there-any-way-to-enable-or-disable-the-spring-bean-definition-in-applicationc
    • PropertyPlaceholderConfigurer example
    0 讨论(0)
  • 2020-12-09 20:15

    Spring provides a mechanism called property placeholders. This way you can set certain properties in a database/properties file and spring will fill them in on startup.

    The class to use for this is located here.

    0 讨论(0)
  • 2020-12-09 20:17

    Use the PropertyPlaceholderConfigurer from Spring, and remove an unused bean :

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location">
             <value>env.properties</value>
         </property>
    </bean>
    
    <bean id="Mybean" class="Bean">   
      <property name="config" ref="config"/>   
    </bean>
    
    <bean id="config" class="Config">
      <property name="x" ref="${x}">
      <property name="y" ref="${y}">
      <property name="z" ref="${z}">
    </bean>
    

    and the env.properties file contains the following properties :

    x=Dev1
    y=Dev2
    z=Dev3
    

    or

    x=Stag1
    y=Stag2
    z=Stag3
    
    0 讨论(0)
  • 2020-12-09 20:25

    Assuming you meant Spring 3.1, rather than Spring 2.1 (which doesn't exist), then you can use the new "Environment Profiles" feature that was introduced in 3.1. This allows you to define a set of beans for each of your environments, and then select the "active" one at runtime.

    See this SpringSource Blog Entry for examples.

    0 讨论(0)
  • 2020-12-09 20:30
    1. setup up the placeholder bean by specfiy, let spring know you want the placeholder
    2. set up the config for the "my bean" by using the "${env}"

    for example:

    <beans>
    <bean id="configBean" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
               <property name="location"><value>env.properties</value></property>
    </bean> 
    
    <bean id="Mybean" class="Bean">   
      <property name="config" ref="${env}"/>   
    </bean>
    
    </beans>
    

    and you need the add the env = dev key-value to the env.properties file

    0 讨论(0)
  • 2020-12-09 20:34

    PropertyPlaceholderConfigurer is the answer, yet I would imagine that you would like this to happen without the need to stay updating your properties file for each environment.

    My suggestion would therefore be as follows

    1. Use PropertyPlaceholderConfigurer, but do not create a properties file
    2. By default, PropertyPlaceholderConfigurer first tries to find a value in a properties file, but if that fails, it will look for one in system properties

    So all you need to do is to define both beans the same way that you are doing it, i.e. dev and stag.. which is a fine approach since you're clearly showing the different configurations... it would help if you also added some alias to show clearly the setting you want to use.

    Next, pass in a system property defining what mode you are in... and ideally explicitly set PropertyPlaceholderConfigurer to use System properties.

    So.. your config would look something like this

    <bean 
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"     
        systemPropertiesMode="2"/>
    
    <bean id="Mybean" class="Bean">   
      <property name="config" ref="${launch.mode}"/>   
    </bean>
    
    <bean id="dev" name="dev_mode" class="Dev">
      <property name="x" ref="Dev1">
      <property name="y" ref="Dev2">
      <property name="z" ref="Dev3">
    </bean>
    
    <bean id="stag" name="staging_mode" class="Dev">
      <property name="x" ref="Stag1">
      <property name="y" ref="Stag2">
      <property name="z" ref="Stag3">
    </bean>
    

    You can then pass in the property upon startup in the following fashion

    -D<property-name>=<value>
    

    So in this case you'd use

    -Dlaunch.mode=dev_mode
    

    Or

    -Dlaunch.mode=staging_mode
    

    And you won't need to touch any of the configuration files.

    Just a further note on systemPropertiesMode, accepted values are the following:

    • 0 - never look in system properties
    • 1 - use system properties as a fallback (i.e. if not found in properties files)
    • 2 - system properties always override (the mode i'm suggesting)

    Hope it helps :)

    Note: This recommendation is only applicable to Spring < 3.1, since from 3.1 onward, the recommended approach is to use @Profile

    0 讨论(0)
提交回复
热议问题