上海十大外贸公司,长沙优化排名,鄂州市官网,律师网站建设哪家专业目录 一、Conditional注解作用 二、Conditional源码解析
2.1 Conditional源码
2.2 Condition源码
三、Conditional案例
3.1 Conditional作用在类上案例
3.1.1 配置文件
3.1.2 Condition实现类
3.1.3 Bean内容类
3.1.4 Config类
3.1.5 Controller类
3.1.6 测试结果
3…目录 一、Conditional注解作用 二、Conditional源码解析
2.1 Conditional源码
2.2 Condition源码
三、Conditional案例
3.1 Conditional作用在类上案例
3.1.1 配置文件
3.1.2 Condition实现类
3.1.3 Bean内容类
3.1.4 Config类
3.1.5 Controller类
3.1.6 测试结果
3.2 Condition作用在类上且多个条件
3.2.1 增加一个Condition实现类
3.2.2 Config2类
3.3 Conditional注入到方法上
3.3.1 Bean内容类
3.3.2 Condition实现类
3.3.3 Config配置类
3.3.4 Controller测试类
3.3.5 测试结果 四、Conditional系列注解拓展
4.1 Component容器和Bean容器的区别
4.2 Conditonal注解拓展
4.2.1 ConditionalOnClass
4.2.1.1 config类
4.2.1.2 Controller类
4.2.1.3 结果
4.2.2 ConditionalOnMissingClass
4.2.2.1 Config
4.2.2.2 Controller
4.2.2.3 测试
4.2.3 ConditionalOnBean
4.2.3.1 config
4.2.3.2 Controller 4.2.3.3 测试结果
4.2.4 ConditionalOnSingleCandidate
4.2.4.1 config 4.2.4.2 Controller 4.2.4.3 测试结果
4.2.5 ConditionalOnWebApplication
4.2.5.1 config
4.2.5.2 Controller 4.2.5.3 结果
4.2.6 ConditionalOnProperty
4.2.6.1 yml文件内容
4.2.6.2 config
4.2.6.3 Contoller
4.2.6.4 测试结果 一、Conditional注解作用 Conditional中文翻译是条件的意思Conditional注解的作用是按照一定的条件进行判断满足条件给容器注册bean。 二、Conditional源码解析
2.1 Conditional源码
Target({ElementType.TYPE, ElementType.METHOD})
Retention(RetentionPolicy.RUNTIME)
Documented
public interface Conditional {Class? extends Condition[] value();
}
从源码中可以看到Conditional只有一个数组参数也就是说明传递的参数是可以多个的但这个参数是要求继承Condition类。
2.2 Condition源码
FunctionalInterface
public interface Condition {boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
Condition是一个函数式接口matches就是它的比较方法如果为true那么就注入如果为false则不注入
三、Conditional案例
3.1 Conditional作用在类上案例
3.1.1 配置文件
enable:flag: true
3.1.2 Condition实现类
public class TestCondition implements Condition {Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata annotatedTypeMetadata) {Environment environment context.getEnvironment();String flagString environment.getProperty(enable.flag);// 如果flagString为true则直接返回trueif(Boolean.parseBoolean(flagString)){return true;}return false;}
}
3.1.3 Bean内容类
public class TestBean {private String name;public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic String toString() {return name 是TestBean;}
}
3.1.4 Config类
Conditonal注解作用在类上并且判断的条件只有一个
Configuration
Conditional(TestCondition.class)
public class TestConfig {Beanpublic TestBean testBean(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}
}
3.1.5 Controller类
controller用于测试 注意点:Autowired注解后面建议加上requiredfalse,这样就算Condition实现类(对应上面的TestCondition类)返回的结果为false那么项目也不会启动报错如果没有加上当Condition实现类返回为false的时候项目启动过程会报Field config in com.common.commonframework.TestController required a bean of type com.common.commonframework.TestConfig that could not be found.错误 RestController
public class TestController {//如果为false启动的时候在这一步会报错可以添加成Autowired(required false)private TestConfig config;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config);System.out.println(config.testBean());}}
3.1.6 测试结果 3.2 Condition作用在类上且多个条件
3.2.1 增加一个Condition实现类
public class TestCondition2 implements Condition {Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {//直接返回false,用于测试return false;}
}
3.2.2 Config2类
Conditional多个条件 注意点:下面的代码由于TestConditon2知己诶返回的是false所以是一定会注入失败的 // TestCondition为false,所以在这个地方是一定会注入失败的
Configuration
Conditional({TestCondition.class,TestCondition2.class})
public class TestConfig2 {Beanpublic TestBean testBean(){return new TestBean();}
}
3.3 Conditional注入到方法上
3.3.1 Bean内容类
public class TestBean2 {private String address;public String getAddress() {return address;}public void setAddress(String address) {this.address address;}Overridepublic String toString() {return 测试方法Bean;}
}
3.3.2 Condition实现类 这个实现类直接返回结果直接为false用于测试 public class TestCondition3 implements Condition {Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {return false;}
}
3.3.3 Config配置类
Configuration
public class TestConfig3 {BeanConditional({TestCondition3.class})public TestBean2 testBean3(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(上海);return testBean2;}
}
3.3.4 Controller测试类
RestController
public class TestController {Autowiredprivate TestConfig3 config3;GetMapping(/test)public void printImportBeanInfo() {//因为Conditional修饰的是在方法上,所以TestConfig3是会注入进去的System.out.println(config3);System.out.println(config3.testBean3());}
}
3.3.5 测试结果 由于在TestConfig3的方法上面修饰的Conditonal注解返回的是false,所以我们在调用对应的Bean的时候会直接报No bean named xx available错误 四、Conditional系列注解拓展
springboot提供的Conditonal系列注解作用:对Component,Bean等容器注解进行校验。校验是否满足指定的条件只有满足指定的条件时才会将对应的内容放到容器里面。如果在启动过程当中直接报了Bean容器重复那么建议直接用Conditional注解处理。
4.1 Component容器和Bean容器的区别 Component作用于类,Bean作用于方法 Component是通过路劲扫描的方式自动装配到bean容器中而Bean是将方法返回值作为bean自动装配到IOC容器中 Bean功能比Component的功能更加强大当我们需要引用外部类并需要将它注入到IOC容器时,Component注解是做不到的但Bean可以做到。 4.2 Conditonal注解拓展
4.2.1 ConditionalOnClass 当给定的类名在类路径上存在则实例化当前Bean 4.2.1.1 config类
TestBean2类在文章的上面
Configuration
public class TestConfig4 {BeanConditionalOnClass(TestBean2.class) //当TestBean2存在,那么这个bean就会注入到容器public TestBean2 testBean3(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(北京);return testBean2;}BeanConditionalOnClass(name com.common.commonframework.TestBean2) //也可以通过路径直接获取对应的类public TestBean2 testBean4(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(北京);return testBean2;}
}
4.2.1.2 Controller类
RestController
public class TestController {Autowiredprivate TestConfig4 config4;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config4);System.out.println(config4.testBean3());System.out.println(config4.testBean4());}
}
4.2.1.3 结果
因为TestBean2这个类存在所以成功注入 4.2.2 ConditionalOnMissingClass 当给定的类名在类路径上不存在则实例化当前Bean 4.2.2.1 Config
Configuration
public class TestConfig5 {BeanConditionalOnMissingClass({ com.common.commonframework.TestBean2}) // 如果不存在TestBean2这个类就将Bean注入容器,目前存在所以会失败public TestBean2 testBean3(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(北京);return testBean2;}
}
4.2.2.2 Controller
RestController
public class TestController {Autowiredprivate TestConfig5 config5;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config5);System.out.println(config5.testBean3());}
}
4.2.2.3 测试
提示失败因为TestBean2是存在的 4.2.3 ConditionalOnBean 当给定的在bean存在时,则实例化当前Bean 4.2.3.1 config
Configuration
public class TestConfig6 {Beanpublic TestBean testBean(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}BeanConditionalOnBean(name testBean) //这个会成功因为存在testBean这个容器public TestBean2 testBean3(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(北京);return testBean2;}BeanConditionalOnBean(name testBean2) //这个会失败因为不存在testBean2这个Beanpublic TestBean2 testBean4(){TestBean2 testBean2 new TestBean2();testBean2.setAddress(北京);return testBean2;}
}
4.2.3.2 Controller
RestController
public class TestController {Autowiredprivate TestConfig6 config6;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config6);System.out.println(config6.testBean3());System.out.println(config6.testBean4());}
} 4.2.3.3 测试结果
testBean3成功,testBean4失败 4.2.4 ConditionalOnSingleCandidate 只有指定的类已存在于BeanFactroy容器中且只有一个实例时才会作为bean放到容器。如果有多个则指定首选的bean。ConditionalOnSingleCandidate是ConditionalOnBean的一种情况满足前者时一定满足后者满足后者时不一定满足前者 4.2.4.1 config
下面的案例是自定义bean然后注入到BeanFactory之中springboot实际上有很多bean在启动过程当中会自动注入BeanFactory不需要我们手动再去注入BeanFactory比如我们常用的RedisConnectionFactory等等
Configuration
public class TestConfig7 implements InitializingBean, BeanFactoryAware {public ConfigurableListableBeanFactory beanFactory;BeanConditionalOnSingleCandidate //自定义的bean注入了BeanFactory所以会成功public TestBean testBean(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {this.beanFactory (beanFactory instanceof ConfigurableListableBeanFactory)? (ConfigurableListableBeanFactory) beanFactory : null;}Overridepublic void afterPropertiesSet() throws Exception {TestBean testBean new TestBean();testBean.setName(java);testBean.toString();beanFactory.registerSingleton(testBean,testBean);}
} 4.2.4.2 Controller
RestController
public class TestController {Autowiredprivate TestConfig7 config7;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config7);System.out.println(config7.testBean());}
} 4.2.4.3 测试结果 4.2.5 ConditionalOnWebApplication
指定对应的web应用类型才会做为bean放到容器中
4.2.5.1 config
Configuration
public class TestConfig8 {BeanConditionalOnWebApplication(type ConditionalOnWebApplication.Type.SERVLET) //web应用类型是servlet应用就会注入beanpublic TestBean testBean(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}BeanConditionalOnWebApplication(type ConditionalOnWebApplication.Type.REACTIVE) //web应用类型是reactive应用就会注入beanpublic TestBean testBean2(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}
}
4.2.5.2 Controller
RestController
public class TestController {Autowiredprivate TestConfig8 config8;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config8);System.out.println(config8.testBean());System.out.println(config8.testBean2());}
} 4.2.5.3 结果
从结果可以看到一个testBean成功一个testBean2失败因为我的应用类型是servlet 4.2.6 ConditionalOnProperty
yml或者properties文件只有当配置条件满足要求时才会放到bean容器
4.2.6.1 yml文件内容
conditional:test: 1
4.2.6.2 config
Configuration
public class TestConfig9 {BeanConditionalOnProperty(conditional.test)public TestBean testBean(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}ConditionalOnProperty(conditional.test.test)Beanpublic TestBean testBean2(){TestBean testBean new TestBean();testBean.setName(java);testBean.toString();return testBean;}
}
4.2.6.3 Contoller
RestController
public class TestController {Autowiredprivate TestConfig9 config9;GetMapping(/test)public void printImportBeanInfo() {System.out.println(config9);System.out.println(config9.testBean());System.out.println(config9.testBean2());}
}
4.2.6.4 测试结果
因为testBean对应的配置存在所以会成功testBean2对应的配置在配置文件不存在所以失败了