我们可以有条件地申报春豆吗?

有没有办法可以像有条件地声明一个Spring bean:

 

它将是有用的,而不必使用配置文件。 我没有考虑具体的用例,但它来到我身边。

您可以使用Spring 4中的 @Conditional或Spring Boot中的 @ConditionalOnProperty

  • 1.使用Spring4( 仅限 ),

    如果你使用弹簧 ,这可能是矫枉过正

首先,创建一个Condition类,ConditionContext可以在其​​中访问Environment:

 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:

 @Bean @Conditional(MyCondition.class) public ObservationWebSocketClient observationWebSocketClient(){ //return bean } 
  • 2.使用Spring Boot

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

在你的abcd.properties文件中,

 server.host=localhost 

我有一个片段用于这样的事情。 它检查在注释中设置的属性的值,因此您可以使用类似的东西

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

它甚至允许您定义具有相同名称的不同bean:

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

这两个可以同时声明,允许你有一个名为bean的"service"具有不同的实现,具体取决于属性是打开还是关闭……

它自己的代码片段:

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