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接口来更 ...
随机推荐
- 20145316《Java程序设计》第9周学习总结
20145316<Java程序设计>第9周学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC(Ja ...
- RabbitMQ的安装及集群搭建方法
RabbitMQ安装 1 安装erlang 下载地址:http://www.erlang.org/downloads 博主这里采用的是otp_src_19.1.tar.gz (200MB+) [roo ...
- Java:延迟功能的Robot在Lunix系统上会报错
Java:延迟功能的Robot在Lunix系统上会报错 关于延迟功能的Robot: 今天开发过程中发现,本机开发好的项目,部署到Lunix服务器竟然报错!查了代码发现: Robot r = new R ...
- 转载:vsftp中的local_umask和anon_umask
转载出处:http://blog.sina.com.cn/s/blog_67c5699001010e3e.html umask是unix操作系统的概念,umask决定目录和文件被创建时得到的初始权限u ...
- 学号20145303 《Java程序设计》第一周学习总结
学号20145303 <Java程序设计>第一周学习总结 教材学习内容总结 *dos命令行: dir:列出当前目录下的文件及文件名 md:创建目录 rd:删除目录.为空时文件夹(文件夹为空 ...
- Linux kernel 编译问题记录【转】
本文转载自:http://sunyongfeng.com/201701/programmer/linux/kernel_compile_fail.html 编译内核出现以下错误 Can't use ' ...
- mysql中group by存在局限性探讨(待续)
现在有一个需求:在2018年游戏充值记录表(字段主要有: user_name , money , game_id , 表有6000w行)查找出哪些人在某段日期内累计充值金额在100~500元范围内的, ...
- [ACM]51nod 贪心专题
目录 A 低买高卖 C 接水问题 D做任务一 E做任务三 51nod一个贪心专题,大多数都是见过的套路,做题找找感觉,有些题解思路懒得写了,直接贴毕姥爷的直播题解了 A 低买高卖 考虑股票市场,一共有 ...
- java高级特性(1)--理解面向对象思想
前言: 优秀的代码具备:高性能.可重用.可扩展.易维护.易理解 具体实现: 高性能:合理使用算法,数据结构等等 可重用:封装.继承 可扩展:多态 易维护.易理解:命名规范 + 注解 面向对象是一种思想 ...
- Asp.Net MVC向视图View传值的三种方法
本文将总结Asp.Net MVC向视图View传值的三种常见的方法: ----------------------------------------------------------------- ...