Spring中@Conditional注解详解

简介: Spring中@Conditional注解详解

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站点击跳转浏览。


@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean。


@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    Class<? extends Condition>[] value();
}


从代码中可以看到,需要传入一个Class数组,并且需要继承Condition接口:


@FunctionalInterface
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}


Condition是个接口,需要实现matches方法,返回true则注入bean,false则不注入。

用法如下


下面举例测试Condition的注入Bean


首先创建Dog类


@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dog {
    private String name;
    private String gender;
}


然后创建MyCondition类


重写matches方法, 返回true则注入bean,false则不注入

如果容器中注入了 dog 就返回true


public class MyCondition implements Condition {
    /**
     * 重写matches方法, 返回true则注入bean,false则不注入。
     * */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 如果容器中注入了 dog 就返回true
        if(beanFactory.containsBean("dog")){
            return true;
        }
        return false;
    }
}


定义两个Bean


@Configuration
public class MyConfig {
    @Bean("dog")
    //@ConditionalOnBean(name = {"dog2"})
    public Dog dog1(){
        return new Dog("金毛","公");
    }
    @Bean("dog1")
    @Conditional(value = MyCondition.class)
    public Dog dog2(){
        return new Dog("拉布拉多","母");
    }
}


测试方法AnnotationConfigApplicationContext


AnnotationConfigApplicationContext是一个独立的应用上下文,它接受带注释的类作为输入。

例如@Configuration或@Component。 可以使用scan()查找 Bean,也可以使用register()注册 Bean。


public class tets {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
         Map<String, Dog> beansOfType = applicationContext.getBeansOfType(Dog.class);
        System.out.println(beansOfType);
    }
}


测试结果如下



如果将MyCondition类中逻辑改为,如果如果容器中之前注入了 dog 就返回false,不注入其他的,

即:


public class MyCondition implements Condition {
    /**
     * 重写matches方法, 返回true则注入bean,false则不注入。
     * */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
        // 如果容器中之前注入了 dog 就返回false
        if(beanFactory.containsBean("dog")){
            return false;
        }
        return true;
    }
}


那么结果如下:



@Conditional本身还是一个父注解,派生出大量的子注解,如下:

@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。

@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。

@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。

@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。

@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。

@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。

@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。

@ConditionalOnExpression:基于SpEL表达式的条件判断。

@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。

@ConditionalOnResource:当类路径下有指定的资源时触发实例化。

@ConditionalOnJndi:在JNDI存在的条件下触发实例化。

@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。


测试@ConditionalOnBean和@ConditionalOnMissingBean注解


修改之前的配置类如下


@Configuration
public class MyConfig {
    @Bean("dog")
    public Dog dog1(){
        return new Dog("金毛","公");
    }
    @Bean("dog1")
    @ConditionalOnBean(name = {"dog"})// spring容器中有dog这个Bean 才会创建dog1
//    @ConditionalOnMissingBean(name = {"dog"})// spring容器中不存在 dog这个Bean 才会创建dog1
    public Dog dog2(){
        return new Dog("拉布拉多","母");
    }
}


结果如下:



然后再将第二个注释放开,第一个注释注释掉

结果如下:



结语


🔥一个人可以掌握知识,但只有与他人交流才能形成智慧。

🔥One person can acquire knowledge, but wisdom is formed only in the exchange with others.

🏆 我坚信人与人之间的差距是表面上是财富的差距,本质上是大脑中认知的差距,


我们下期再见。

相关文章
|
10天前
|
前端开发 Java 开发者
深入理解Spring Boot中的@Service注解
【4月更文挑战第22天】在 Spring Boot 应用开发中,@Service 注解扮演着特定的角色,主要用于标识服务层组件。本篇技术博客将全面探讨 @Service 注解的概念,并提供实际的应用示例,帮助开发者理解如何有效地使用这一注解来优化应用的服务层架构
52 1
|
11天前
|
Java 开发者 Spring
深入理解Spring Boot的@ComponentScan注解
【4月更文挑战第22天】在构建 Spring Boot 应用时,@ComponentScan 是一个不可或缺的工具,它使得组件发现变得自动化和高效。这篇博客将详细介绍 @ComponentScan 的基本概念、关键属性及其在实际开发中的应用。
26 4
|
12天前
|
Java 开发者 Spring
深入理解 Spring Boot 中的 @EnableAutoConfiguration 注解:概念与实践
【4月更文挑战第21天】在 Spring Boot 项目中,@EnableAutoConfiguration 注解是实现自动配置的核心,它可以根据项目的依赖和配置,自动地配置 Spring 应用程序中的 Bean
29 3
|
12天前
|
Java API 网络架构
深入理解 Spring Boot 中的 @RestController 注解:概念与实践
【4月更文挑战第20天】在现代Web开发中,创建RESTful服务已成为常态。Spring Boot通过提供@RestController注解,极大简化了REST API的开发过程。本篇博客旨在详细介绍@RestController的概念、优势以及在Spring Boot项目中的具体应用方法。
31 8
|
12天前
|
Java 开发者 Spring
Spring Framework 中的 @Autowired 注解:概念与使用方法
【4月更文挑战第20天】在Spring Framework中,@Autowired 注解是实现依赖注入(Dependency Injection, DI)的一种非常强大的工具。通过使用 @Autowired,开发者可以减少代码中的引用绑定,提高模块间的解耦能力
31 6
|
2月前
|
XML Java 数据库连接
spring boot 参数的过滤注解与实战
在Spring Boot应用中,对于入参的过滤,通常会涉及到对Web层的数据验证和处理。Spring Boot借助Spring框架提供了强大的验证框架支持,主要基于JSR-303/JSR-380(Bean Validation API)规范,以及Spring自身的@Valid或@Validated注解来实现请求参数的验证。以下是一些常见的使用案例来展示如何对参数进行过滤和验证。
30 1
|
2月前
|
Java Spring 容器
【Java】Spring如何扫描自定义的注解?
【Java】Spring如何扫描自定义的注解?
37 0
|
2月前
|
Java 测试技术 数据库
SpringBoot:@Profile注解和Spring EL
SpringBoot:@Profile注解和Spring EL
|
2月前
|
存储 缓存 Java
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
【Spring原理高级进阶】有Redis为啥不用?深入剖析 Spring Cache:缓存的工作原理、缓存注解的使用方法与最佳实践
|
2月前
|
Java 数据库 Spring
【spring(四)】Spring事务管理和@Transactional注解
【spring(四)】Spring事务管理和@Transactional注解