Java 我们可以有条件地声明Springbean吗?
有没有一种方法可以有条件地声明Springbean,如:Java 我们可以有条件地声明Springbean吗?,java,spring,Java,Spring,有没有一种方法可以有条件地声明Springbean,如: <bean class="path.to.the.class.MyClass" if="${1+2=3}" /> 这将是有用的,而不必使用配置文件。 我脑子里没有具体的用例,但我想到了。您可以使用Spring4中的@Conditional或SpringBoot中的@Conditional属性 使用Spring4(仅限) 如果您未使用Spring启动,则此可能会造成过度伤害 首先,创建一个条件类,其中条件上下文可以访问环境
<bean class="path.to.the.class.MyClass" if="${1+2=3}" />
这将是有用的,而不必使用配置文件。
我脑子里没有具体的用例,但我想到了。您可以使用Spring4中的@Conditional或SpringBoot中的@Conditional属性
条件
类,其中条件上下文
可以访问环境
:
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.使用弹簧护套:
@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,根据属性是开还是关,它有不同的实现
它本身的代码片段:
/**
* 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;
}
}
啊。基于注释的。那绝对是完美的。我忘记了注释,但是在SpringXML中有没有同样的方法呢。。。谷歌给了我一个看起来也可以做到的例子(尽管我不确定在那个例子中使用了哪个版本的Spring,因为它已经很旧了)