@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass、@Conditional和Condition接口的使用
一、@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass@ConditionalOnBean是指当spring容器中有某个bean时才装配。@ConditionalOnClass是指当classpath下有某个类时才装配@ConditionalOnProperty是指当某个配置项为某个值时才装配例如:@ConditionalOn
一、@ConditionalOnBean、@ConditionalOnProperty、@ConditionalOnClass
@ConditionalOnBean是指当spring容器中有某个bean时才装配。@ConditionalOnMissingBean当spring容器中不存在某个bean时才装配
@ConditionalOnClass是指当classpath下有某个类时才装配。@ConditionalOnMissingClass是指当classpath下没有某个类时才装配
@ConditionalOnProperty是指当某个配置项为某个值时才装配。@ConditionalOnMissingProperty是指当某个配置项不等于某个值时才装配
例如:@ConditionalOnBean(name="user")表示当容器中有名字为user的bean时才装配。
下面做下验证测试:
第一步:当没有任何注解时,spring容器里会有三个Runnable类型的bean,名字分别为createRable1,createRable2,createRable3
package com.lsl;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.context.annotation.Bean;
@SpringBootConfiguration
public class MyConfig {
@Bean
public Runnable createRable1(){
System.out.println("=======default======");
return ()->{};
}
@Bean
public Runnable createRable2(){
System.out.println("=======dev======");
return ()->{};
}
@Bean
public Runnable createRable3(){
System.out.println("=======user======");
return ()->{};
}
}
package com.lsl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class SpringbootProviderApplication {
public static void main(String[] args) {
ConfigurableApplicationContext content = SpringApplication.run(SpringbootProviderApplication.class, args);
System.out.println("springname=" + content.getEnvironment().getProperty("springboot.name"));
System.out.println("ds.name=" + content.getEnvironment().getProperty("ds.name"));
System.out.println("ds.password=" + content.getEnvironment().getProperty("ds.password"));
//从容器中获取类型为Runnable的所有bean
System.out.println(content.getBeansOfType(Runnable.class));
}
}
输出结果:
第二步:当分别加上注解时
package com.lsl;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
@SpringBootConfiguration
public class MyConfig {
@Bean
@ConditionalOnBean(name="user")
public Runnable createRable1(){
System.out.println("=======default======");
return ()->{};
}
@Bean
@ConditionalOnClass(name="user")
public Runnable createRable2(){
System.out.println("=======dev======");
return ()->{};
}
@Bean
@ConditionalOnProperty(name="opFlag",havingValue = "save")
public Runnable createRable3(){
System.out.println("=======user======");
return ()->{};
}
}
结果输出:由于没有user的bean所以没有装配
第三步:创建User类,并交给spring容器托管。
package com.lsl;
import org.springframework.stereotype.Component;
@Component
public class User {
}
输出结果:由于spring容器托管了User类,名字且为user,所以createRable1装配了
在默认配置文件加上配置项 ,createRable3也装配了
由于classpath下没有user的bean,所有createRable2没有被装配。
二、@Conditional和Condition接口
上面的三个注解时spring提供的比较常用的几个注解,当然spring还提供了其他类似注解,
比如@ConditionalOnJava,当jdk为某个版本时才装配。
除此之外spring还提供了扩展,利用Condition接口和@Conditional注解自定义扩展功能
一般情况下Condition接口和@Conditional注解要配合使用。
首先是实现Condition接口。
package com.lsl;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Arrays;
import java.util.List;
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String opFlag = conditionContext.getEnvironment().getProperty("opFlag");
String[] beanDefinitionNames = conditionContext.getRegistry().getBeanDefinitionNames();
List<String> strings = Arrays.asList(beanDefinitionNames);
if (strings.contains("user" ) && "save".equals(opFlag)){
return true;
}
return false;
}
}
createRable4()方法上加了 @Conditional(MyCondition.class)注解,表示只有当MyCondition中的方法返回true时才装配。
package com.lsl;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@SpringBootConfiguration
public class MyConfig {
@Bean
@ConditionalOnBean(name="user")
public Runnable createRable1(){
System.out.println("=======default======");
return ()->{};
}
@Bean
@ConditionalOnClass(name="user")
public Runnable createRable2(){
System.out.println("=======dev======");
return ()->{};
}
@Bean
@ConditionalOnProperty(name="opFlag",havingValue = "save")
public Runnable createRable3(){
System.out.println("=======user======");
return ()->{};
}
@Bean
@Conditional(MyCondition.class)
public Runnable createRable4(){
System.out.println("=======MyCondition======");
return ()->{};
}
}
输出结果如下:MyCondition的功能是当配置项opFlag=save且容器中已经注册了user名字的bean时才返回true
这种配合使用的方法非常灵活,可以多看看Condition接口中matchs方法的两个参数,这2个参数能获取好多信息,可以根据信息进行相关逻辑判断是返回true还是false.
更多推荐
所有评论(0)