Spring中@Conditional注解的用法
作者:时间不会赖着不走
这篇文章主要介绍了Spring中@Conditional注解的用法,@Conditional是Spring4新提供的注解,它的作用是按照一定的条件进行判断,满足条件给容器注册bean,需要的朋友可以参考下
@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("拉布拉多","母"); } }
结果如下:
然后再将第二个注释放开,第一个注释注释掉 结果如下:
到此这篇关于Spring中@Conditional注解的用法的文章就介绍到这了,更多相关@Conditional注解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!