@Conditional详解
详解
@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
参数是Condition类的集合看看Condition接口
matches就像正则的那个类一样…应该是true注入,false不注入
测试
创建一个person类,然后创建个配置类,返回一个linux,一个gates,类.
import lombok.AllArgsConstructor;
import lombok.Data;
@Data
@AllArgsConstructor
public class Person {
private String name;
private int age;
}
配置类记得要扫到
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class PersonConfigure {
@Bean(name = "bill")
@Conditional({WindowsCondition.class})
public Person person1() {
return new Person("Bill Gates", 62);
}
@Bean("linus")
@Conditional({LinuxCondition.class})
public Person person2() {
return new Person("Linus", 48);
}
}
然后测试一波,我这是springboot项目,测试比较简单.
import com.alibaba.fastjson.JSON;
import com.ql.servicetest.conditionDemo.Person;
import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import java.util.Map;
public class ConditionTest extends BaseTest implements ApplicationContextAware {
@Test
public void test1() {
Map<String, Person> beansOfType = ApplicationContext.getBeansOfType(Person.class);
String property = ApplicationContext.getEnvironment().getProperty("os.name");
System.out.println("当前系统为:"+property);
System.out.println(JSON.toJSONString(beansOfType));
}
public ApplicationContext ApplicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.ApplicationContext = applicationContext;
}
}
我直接继承baseTest测试类,然后实现ApplicationContextAware得到spring容器,简单方便.一开始不加Conditional注解,就是两个都有,创建两个类LinuxCondition,WindowsCondition分别实现Condition接口,作为@Contional注解的值;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
Environment environment = conditionContext.getEnvironment();
String property = environment.getProperty("os.name");
if (property.contains("Linux")){
return true;
}
return false;
}
}
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
/**
* @param conditionContext:判断条件能使用的上下文环境
* @param annotatedTypeMetadata:注解所在位置的注释信息
* */
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
//获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
//获取当前环境信息
Environment environment = conditionContext.getEnvironment();
//获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
//获得当前系统名
String property = environment.getProperty("os.name");
//包含Windows则说明是windows系统,返回true
if (property.contains("Windows")){
return true;
}
return false;
}
}
这两个类其实就是拿到当前运行环境进行判断,然后返回true,false.
分别将 @Conditional注解加上,然后运行:
发现只注入了gatesPerson类,然后将运行环境改为linux,试一波
结果:
@Conditional注解也可以加在注解上,加在注解上效果也是一样的,
如果多个条件呢?总结就是都返回true才会注入.转载文章的结论.
思考
如果我类上返回true,方法上返回false呢?
如果我类上放回false,方法上返回true呢?
我猜想是如果类上返回了false,那就都不注入,不看你方法上的了,
如果类上返回了true,才会判断方法上的,试一波
第一种,类上为True,
返回
第二种,类上为False
猜想正确,
会先判断类上,如果类上不满足就直接不加载
如果类上满足还好判断方法上满足不满足.
源码
https://github.com/stackXu/study-authconfigure
原文:
转自:
https://blog.csdn.net/xcy1193068639/article/details/81491071