2016-10-04 4 views
16

Gibt es eine Möglichkeit wir eine Spring-Bean mag bedingt erklären können:Können wir Federbohne bedingt deklarieren?

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

Es würde anstatt verwenden Profile nützlich sein. Ich habe keinen bestimmten Anwendungsfall im Sinn, aber es kam zu mir.

Antwort

14

Sie können @Conditional von Spring oder @ConditionalOnProperty von Spring Boot- verwenden.

  • 1.Using Spring4 (nur),

    wenn Sie NICHT Feder mit Boot, diese kann Overkill sein.

zunächst eine Konditionsklasse erstellen, in dem die ConditionContext Zugang zur Umwelt hat:

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")); 
    } 
} 

Dann Anmerkungen versehen Bohne:

@Bean 
@Conditional(MyCondition.class) 
public ObservationWebSocketClient observationWebSocketClient(){ 
    //return bean 
} 
  • 2.Using Frühling Boot:

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

Und in Ihrer abcd.properties Datei,

server.host=localhost 
0

Ich habe einen Ausschnitt für so etwas. Er prüft den Wert einer Eigenschaft, die in der Anmerkung festgelegt ist, so kann man Dinge wie

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

verwendet Es erlaubt Ihnen sogar verschiedene Bohnen mit dem gleichen Namen zu definieren:

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

Diese beiden Dosen wird zugleich erklärt, so dass Sie ein "service" namens Bean mit unterschiedlichen Implementierungen haben, je nachdem, ob das Eigentum an oder aus ist ...

das snippet für sie selbst:

/** 
* 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

Ah. Annotationsbasiert. Das ist absolut perfekt. Ich habe Anmerkungen vergessen, aber gibt es eine Möglichkeit, das Gleiche in Spring XML zu tun? –

+0

Hmmm ... Ein Google gab mir http://robertmaldon.blogspot.nl/2007/04/conditional-defining-spring-beans.html was aussieht, als könnte es auch getan werden (obwohl ich nicht sicher bin, welche Version von Spring wird in diesem Beispiel verwendet, da es * ganz * alt ist) –

Verwandte Themen