2016-10-04 11 views
16

我々は条件付きのようなのSpring Beanを宣言することができる方法があります:それは代わりにプロファイルを使用することの有用であろう条件付きでSpring Beanを宣言できますか?

<bean class="path.to.the.class.MyClass" if="${1+2=3}" /> 

が。 私は特定のユースケースを念頭に置いていませんが、それは私に来ました。

答えて

14

あなたは春ブートから春または@ConditionalOnPropertyから@Conditionalを使用することができます。

  • 1.Using Spring4(のみ)、

    あなたは春ブートを使用してされていない場合は、このは行き過ぎすることができます。

まず、ConditionContextは、環境へのアクセス権を持っている、条件クラスを作成します。

public class MyCondition implements Condition { 
    @Override 
    public boolean matches(ConditionContext context, 
          AnnotatedTypeMetadata metadata) { 
     Environment env = context.getEnvironment(); 
     return null != env 
       && "true".equals(env.getProperty("server.host")); 
    } 
} 

その後、あなたの豆に注釈を付ける:

@Bean 
@Conditional(MyCondition.class) 
public ObservationWebSocketClient observationWebSocketClient(){ 
    //return bean 
} 
  • 2.Using春ブーツ

@ConditionalOnProperty(name="server.host", havingValue="localhost")

そして、あなたのabcd.propertiesファイルで、

server.host=localhost 
0

私はそのようなことのためのスニペットを持っています。

@ConditionalOnProperty(value="usenew", on=true, propertiesBeanName="myprops") 
@Service("service") 
public class newService implements ServiceFunction{ 
    // some new implementation of the service function. 
} 

これら二つのことができます:それはあなたが

@ConditionalOnProperty(value="usenew", on=false, propertiesBeanName="myprops") 
@Service("service") 
public class oldService implements ServiceFunction{ 
    // some old implementation of the service function. 
} 

のようなものを使用することができますので、それも、あなたが同じ名前で異なる豆を定義することができ、注釈に設定されたプロパティの値をチェックしますそれ自体のために...あなたはプロパティがオンかオフかに応じて異なる実装と"service"という名前のBeanを持つことができ、同時に

スニペットを宣言する:

/** 
* Components annotated with ConditionalOnProperty will be registered in the spring context depending on the value of a 
* property defined in the propertiesBeanName properties Bean. 
*/ 

@Target({ ElementType.TYPE, ElementType.METHOD }) 
@Retention(RetentionPolicy.RUNTIME) 
@Conditional(OnPropertyCondition.class) 
public @interface ConditionalOnProperty { 
    /** 
    * The name of the property. If not found, it will evaluate to false. 
    */ 
    String value(); 
    /** 
    * if the properties value should be true (default) or false 
    */ 
    boolean on() default true; 
    /** 
    * Name of the bean containing the properties. 
    */ 
    String propertiesBeanName(); 
} 

/** 
* Condition that matches on the value of a property. 
* 
* @see ConditionalOnProperty 
*/ 
class OnPropertyCondition implements ConfigurationCondition { 
    private static final Logger LOG = LoggerFactory.getLogger(OnPropertyCondition.class); 

    @Override 
    public boolean matches(final ConditionContext context, final AnnotatedTypeMetadata metadata) { 
     final Map attributes = metadata.getAnnotationAttributes(ConditionalOnProperty.class.getName()); 
     final String propertyName = (String) attributes.get("value"); 
     final String propertiesBeanName = (String) attributes.get("propertiesBeanName"); 
     final boolean propertyDesiredValue = (boolean) attributes.get("on"); 

     // for some reason, we cannot use the environment here, hence we get the actual properties bean instead. 
     Properties props = context.getBeanFactory().getBean(propertiesBeanName, Properties.class); 
     final boolean propValue = parseBoolean(props.getProperty(propertyName, Boolean.toString(false))); 
     LOG.info("Property '{}' resolved to {}, desired: {}", new Object[] { propertyName, propValue, "" + propertyDesiredValue }); 
     return propValue == propertyDesiredValue; 
    } 
    /** 
    * Set the registration to REGISTER, else it is handled during the parsing of the configuration file 
    * and we have no guarantee that the properties bean is loaded/exposed yet 
    */ 
    @Override 
    public ConfigurationPhase getConfigurationPhase() { 
     return ConfigurationPhase.REGISTER_BEAN; 
    } 
} 
+0

ああ。アノテーションベース。それは絶対に完璧です。私は注釈を忘れましたが、Spring XMLでも同じことをする方法はありますか? –

+0

Hmmm ... Googleは私にhttp://robertmaldon.blogspot.nl/2007/04/conditionally-defining-spring-beans.htmlを与えました。この例ではSpringが使用されていますが、これはかなり古いものです) –

関連する問題