条件装配:满足Conditional指定的条件,则进行组件注入
用@ConditionalOnMissingBean举例说明
@Configuration(proxyBeanMethods = false)
@ConditionalOnMissingBean(name = "tom")//没有tom名字的Bean时,MyConfig类的Bean才能生效。
public class MyConfig {
@Bean
public User user01(){
User zhangsan = new User("zhangsan", 18);
zhangsan.setPet(tomcatPet());
return zhangsan;
}
@Bean("tom22")
public Pet tomcatPet(){
return new Pet("tomcat");
}
}
public static void main(String[] args) {
//1、返回我们IOC容器
ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args);
//2、查看容器里面的组件
String[] names = run.getBeanDefinitionNames();
for (String name : names) {
System.out.println(name);
}
boolean tom = run.containsBean("tom");
System.out.println("容器中Tom组件:"+tom);//false
boolean user01 = run.containsBean("user01");
System.out.println("容器中user01组件:"+user01);//true
boolean tom22 = run.containsBean("tom22");
System.out.println("容器中tom22组件:"+tom22);//true
}
@Conditional源码
@Conditional来源于spring-context包下的一个注解。Conditional中文是条件的意思,@Conditional注解它的作用是按照一定的条件进行判断,满足条件给容器注册bean。
通过他的注解内部可以发现,他就是一个纯功能性注解,他并没有依赖于其他注解,类上只有三个元注解。
@Target({ElementType.TYPE, ElementType.METHOD}) 使用范围接口、类、枚举、注解、方法
@Retention(RetentionPolicy.RUNTIME): @Retention是用来修饰注解的生命周期的,RetentionPolicy.RUNTIME代表的是不仅被保存到class文件中,jvm加载class文件之后,仍然存在;一直有效!
@Documented: @Documented和@Deprecated注解长得有点像,@Deprecated是用来标注某个类或者方法不建议再继续使用,@Documented只能用在注解上,如果一个注解@B,被@Documented标注,那么被@B修饰的类,生成Javadoc文档时,会显示@B。
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
@Conditional只有一个参数,并且这个参数要求是继承与Condition类,并且参数是个数组,也就是可以 传多个的。Condition类是一个函数式接口(只有一个方法的接口被称为函数式接口)。matches方法就是比较方法,如果为true则注入,如果为false则不注入。
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
@Conditional扩展注解
而除了@Conditional注解外,springboot通过@Conditional注解又扩展了很多注解出来,如下@ConditionalOnBean、@ConditionalOnClass等等…
@ConditionalOnClass
主要是判断是否存在这个类文件,如果有这个文件就相当于满足条件,然后可以注入到容器当中。
当然并不是说容器里面是否有这个类哈,不要理解错了,这也就是我们有时候使用springboot只需要引入个依赖,框架就可以用的原因!
@ConditionalOnMissingClass
@ConditionalOnMissingClass只有一个value属性。他和@ConditionalOnClass功能正好相反。@ConditionalOnClass是class存在为true,而@ConditionalOnMissingClass是不存在为true,也就是存在为false。为fasle就意味着不注入。
@ConditionalOnBean
bean存在的时候注入,不存在的时候不注入,这块就是指的spring的ioc容器了。
@ConditionalOnMissingBean
bean不存在的时候注入,存在的时候为false。跟@ConditionalOnBean正好是相反的。
@ConditionalOnProperty
@ConditionalOnProperty主要可用于通过和springboot当中application配置文件来使用。在实战当中我们也可以通过他来实现配置化管理bean。
其他注解
@ConditionalOnJava:只有运行指定版本的 Java 才会加载 Bean
@ConditionalOnWebApplication 和 @ConditionalOnNotWebApplication:只有运行在(不在)web 应用里才会加载这个 bean
@ConditionalOnCloudPlatform:只有运行在指定的云平台上才加载指定的 bean
@ConditionalOnJndi:只有指定的资源通过 JNDI 加载后才加载 bean
@ConditionalOnExpression(“${test.express}==true”) :可通过spring提供的spEL表达式灵活配置,当表达式为true的时候,才会实例化一个Bean
@ConditionalOnSingleCandidate(UserService.class) :表示ioc容器中只有一个UserService类型的Bean,才生效
@ConditionalOnResource:指定的静态资源⽂件存在 才加载
————————————————
引用原文链接:https://blog.csdn.net/weixin_43888891/article/details/127503336