SpringInAction--条件化的Bean
学习了profile bean之后,发现有的时候bean还是有根据环境来选择的余地的,那么假设我们希望某个bean只有当另外某个特定的bean也声明了之后才会创建。我们还可能要求只有某个特定的环境变量设置之后,才会创建某个bean。
在Spring 4之前,很难实现这种级别的条件化配置,但是Spring 4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽略。
今天就来学习下 条件化的Bean。
创建方法是在方或者类上 添加一个@Conditional(xxx.class) xxx.class表示一个逻辑性的内容,当满足需求的时候返回true这样一来这个@Bean就会被创建,反之就不创建
@Bean
@Conditional(XXX.class)
这样一来,跟profile还是有点相似的,但是比他要强大的多的多。。。我们看Profile源码,你会发现Profile也添加了@Conditional,代码如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@Documented
@Conditional({ProfileCondition.class})
public @interface Profile {
String[] value();
}
这个时候在查看下ProfileCondition.class
class ProfileCondition implements Condition {
ProfileCondition() {
}
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if(context.getEnvironment() != null) {
MultiValueMap attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
if(attrs != null) {
Iterator var4 = ((List)attrs.get("value")).iterator();
Object value;
do {
if(!var4.hasNext()) {
return false;
}
value = var4.next();
} while(!context.getEnvironment().acceptsProfiles((String[])((String[])value)));
return true;
}
}
return true;
}
}
这个时候我们会发现 有一个接口 Condition,之所以那么牛逼 估计全靠这个吧,看一下源码:
public interface Condition {
boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2);
}
有了ConditionContext,我们可以做到如下几点:
- 借助getRegistry()返回的BeanDefinitionRegistry检查bean定义;
- 借助getBeanFactory()返回的ConfigurableListableBeanFactory检查bean是
- 否存在,甚至探查bean的属性;
- 借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是
- 什么;
- 读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;
- 借助getClassLoader()返回的ClassLoader加载并检查类是否存在。
有了AnnotatedTypeMetadata则能够让我们检查带有@Bean注解的方法上还有什么其他的注解。
下面就以例子来说明:
假设有两个赏金猎人,一个高级的,一个初级的,他们各种会根据各自的赏金面板的消息(即Condition接口的实现类),决定是否去开始猎杀目标,下面先创造猎人接口以及两个猎人
public interface BountyHunter {
void BeginHuntAndKill();
}
高级赏金猎人
public class SeniorBountyHunter implements BountyHunter {
public void BeginHuntAndKill() {
System.out.println("我是高级赏金猎人哇哈哈哈,现在已有任务发布,我可以去做任务了!");
}
}
初级赏金猎人
public class PrimaryBountyHunter implements BountyHunter {
public void BeginHuntAndKill() {
System.out.println("我是初级赏金猎人乌卡卡卡,现在已有任务发布,我可以去做任务了!");
}
}
然后分别再创建 各自的任务面板
高级任务
public class SeniorBounty implements Condition {
public boolean matches(ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata) {
/**
* 各种自己想要的验证,然后根据结果来返回 一个boole值
*/
if (conditionContext.getEnvironment().acceptsProfiles("task")) {
return true;
} else {
return false;
}
}
}
初级任务
public class PrimaryBounty implements Condition {
public boolean matches(ConditionContext conditionContext,
AnnotatedTypeMetadata annotatedTypeMetadata) {
/**
* 各种自己想要的验证,然后根据结果来返回 一个boole值
*/
if (conditionContext.getEnvironment().acceptsProfiles("task")) {
return true;
} else {
return false;
}
}
}
任务有了,人物也有了,下面就是需要一个人大喊一下:有新的任务发布了,赶紧去看啊!!
也就是Bean配置类
@Configuration
public class TaskConfig { @Bean
@Conditional(PrimaryBounty.class)
public BountyHunter ThePrimaryBountyHunter() {
return new PrimaryBountyHunter();
} @Bean
@Conditional(SeniorBounty.class)
public BountyHunter TheSeniorBountyHunter() {
return new SeniorBountyHunter();
}
}
现在有人通知了,让我们看一下是否有人领任务,开始去猎杀!
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TaskConfig.class)
@ActiveProfiles("task")
public class TaskBegin { @Autowired
SeniorBountyHunter seniorBountyHunter; @Autowired
PrimaryBountyHunter primaryBountyHunter; @Test
public void TaskLog() {
if (primaryBountyHunter != null) {
primaryBountyHunter.BeginHuntAndKill();
}
if (seniorBountyHunter != null) {
seniorBountyHunter.BeginHuntAndKill();
}
}
}
这边我们是根据Profile来测试的,根据这个判断任务是否满足,当然我们也可以不根据配置环境,我们可以根据任务的的属性是否跟猎人相匹配(即 可以根据 @Conditional(xxx.class) xxx.class 类中的判断,该Bean是否有我们需要的属性 )
测试结果

以上就是条件化的bean配置 简单小例子,如有错误,请指出,谢谢~
代码:https://github.com/eoooxy/springinaction test下 的com.bean.condition中
SpringInAction--条件化的Bean的更多相关文章
- 第3章—高级装配—条件化的Bean
条件化的Bean 通过活动的profile,我们可以获得不同的Bean.Spring 4提供了一个更通用的基于条件的Bean的创建方式,即使用@Conditional注解. @Conditional根 ...
- 002Conditional条件化创建bean
01.条件化配置bean @Bean @Conditional(MagicExistsCondition.class)---->条件化创建bean public MagicBean magicB ...
- Spring入门(六):条件化的bean
1. 概念 默认情况下,Spring中定义的bean在应用程序启动时会全部装配,不管当前运行的是哪个环境(Dev,QA或者Prod),也不管当前运行的是什么系统(Windows或者Linux),但有些 ...
- (二)spring 高级装配-Condition -条件化的bean
Condition:满足某个特定条件的情况下创建bean 条件化配置bean: a:@Conditional 指定一个class ,它指明了通过条件对比的类.如果没有指定class则通过Condito ...
- Spring 梳理-profile与条件化定义bean
定义profile <beans> //root <beans profile="dev"> <bean id=.../> </beans ...
- 【Java Web开发学习】Spring4条件化的bean
[Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...
- Spring高级装配(二) 条件化的bean
如果你希望一个bean在特定的条件下才会出现: 应用的类路径下包含特定的库时才创建 只有当某个特定的bean也声明之后才会创建 某个特定的环境变量设定之后才创建某个bean 在Spring 4之前,很 ...
- 001profile条件化创建bean
01.类级别条件创建 @Configuration @Profile("dev") public class Aclass{}---->影响整个类,包括类的注解.开发环境,类 ...
- @Condition 条件化注册Bean
看<Spring源码深度解析>笔记 1.@Condition: 按照一定的条件进行判断,满足条件给容器中注册bean:实例: 根据系统给容器中注册Bean,如果是windows注册(“bi ...
- spring对bean的高级装配之基于@Conditional条件化装配
上篇介绍了如何基于profile来条件化创建bean,spring会根据profile的激活状态来进行创建;这篇介绍如何基于spring4.0引入的@Conditional和Condition接口来更 ...
随机推荐
- Tomcat之并发优化
1.位置: (1)/opt/tomcat7/conf下的server.xml文件中<Connector>节点的配置优化,记得先备份. (2)出厂默认(在server.x ...
- 20145321 《Java程序设计》第3周学习总结
20145321 <Java程序设计>第3周学习总结 教材学习内容总结 第四章 4.1 类与对象 1.定义类:类定义时用关键词 class. 一个原始码中可以有多个类定义,但只能有一个公开 ...
- 20145329《Java程序设计》第八周学习总结
教材学习内容总结 日志 1.java.util.logging包提供了日志功能相关类与接口. 2.使用日志的起点是Logger类,Longer类的构造函数标示为protected,不同包的类药取得Lo ...
- Java中private、protected、public和default的区别-001
public: 具有最大的访问权限,可以访问任何一个在classpath下的类.接口.异常等.它往往用于对外的情况,也就是对象或类对外的一种接口的形式. protected: 主要的作用就是用来保护子 ...
- Ubuntu16.04多个版本GCC编译器的安装和切换【转】
本文转载自:https://www.cnblogs.com/uestc-mm/p/7511063.html 这几天在配置交叉编译ARM开发板的linux内核的过程中碰到了很多问题,其中包括了GCC版本 ...
- vROPS中获取虚拟机在VC中的UUID
vROPS中虚拟机对象的ID为resourceID,跟vCenter中虚拟机的UUID是不一致的,因此想要将vROPS中的虚拟机和vCenter中的虚拟机对应肯定不能靠虚拟机名称,而是一定要靠UUID ...
- 4.9版本linux内核的ina220电流检测芯片源码在哪里
答:在drivers/hwmon/ina2xx.c中,内核配置项为CONFIG_SENSORS_INA2XX Location: -> Device Drivers -> Hardware ...
- cmd中如何查看环境变量
查看所有环境变量 set 查看某一个环境变量 C:\WINDOWS\system32>set no_proxyNO_PROXY=localhost,127.0.0.1,172.31.212.14 ...
- mac下搭建基于vue-cli 3.0的Element UI 项目
1.安装yarn管理工具(包含node.js); 2.安装全局vue-cli全家桶: yarn global add @vue/cli 3.创建.测试一个vue-cli项目: vue create a ...
- jQuery基本筛选选择器
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...