@Conditional详解

文章目录

    • 详解
    • 测试
    • 思考
    • 源码
    • 原文:

详解

@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
@Conditional详解_第1张图片
参数是Condition类的集合看看Condition接口
@Conditional详解_第2张图片
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项目,测试比较简单.
@Conditional详解_第3张图片

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详解_第4张图片
结果:
在这里插入图片描述
@Conditional注解也可以加在注解上,加在注解上效果也是一样的,
如果多个条件呢?总结就是都返回true才会注入.转载文章的结论.
@Conditional详解_第5张图片

思考

如果我类上返回true,方法上返回false呢?
如果我类上放回false,方法上返回true呢?
我猜想是如果类上返回了false,那就都不注入,不看你方法上的了,
如果类上返回了true,才会判断方法上的,试一波
第一种,类上为True,
@Conditional详解_第6张图片
返回
在这里插入图片描述
第二种,类上为False
在这里插入图片描述
猜想正确,

会先判断类上,如果类上不满足就直接不加载
如果类上满足还好判断方法上满足不满足.

源码

https://github.com/stackXu/study-authconfigure
@Conditional详解_第7张图片

原文:

转自:
https://blog.csdn.net/xcy1193068639/article/details/81491071

你可能感兴趣的:(spring)