Spring入门(六):条件化的bean
1. 概念
默认情况下,Spring中定义的bean在应用程序启动时会全部装配,不管当前运行的是哪个环境(Dev,QA或者Prod),也不管当前运行的是什么系统(Windows或者Linux),但有些使用场景下,我们可能需要条件化的装配某些bean,即当满足某一条件时,装配某些bean,当不满足某一条件时,就忽略掉某些bean。
这个条件可以很简单,比如当某个jar包存在时,当存在某个环境变量时,也可以很复杂。
针对这个使用场景,Spring中提供了@Conditional
注解来实现条件化的bean。
2. 示例
为了更好的理解,我们通过具体的代码示例来理解下条件化的bean的实现方式。
由于Windows系统和Linux系统显示列表的命令不同,Windows下是dir,Linux下是ls,因此我们的需求是,应用程序启动时自动根据当前系统装配需要的bean,比如我的电脑系统是Windows 7,那就只装配Windows系统所需要的bean。
首先,定义一个接口ListService,该接口只包含一个方法showListCmd:
package chapter03.conditional;
public interface ListService {
String showListCmd();
}
然后定义该接口的2个实现类WindowsListService和LinuxListService:
package chapter03.conditional;
public class WindowsListService implements ListService {
public WindowsListService() {
System.out.println("This is WindowsListService constructor");
}
@Override
public String showListCmd() {
return "dir";
}
}
package chapter03.conditional;
public class LinuxListService implements ListService {
public LinuxListService() {
System.out.println("This is LinuxListService constructor");
}
@Override
public String showListCmd() {
return "ls";
}
}
然后分别定义Windows系统和Linux系统的判断条件:
package chapter03.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Windows");
}
}
package chapter03.conditional;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Linux");
}
}
值得注意的是,这2个类都需要实现Condition接口,并重写方法matches(),如果该方法返回true时,使用该条件的1个或多个bean就会被装配,如果该方法返回false,使用该条件的1个或多个bean就会被忽略。
然后,定义Java配置类ConditionalConfig:
package chapter03.conditional;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ConditionalConfig {
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
}
@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
}
}
这里声明bean时除了使用@Bean注解,还使用了@Conditional注解,这个注解是实现条件化的bean的关键,它的参数可以传递任何实现了Condition接口并重写了matches()方法的类,这里传递的是我们上面定义的WindowsCondition和LinuxCondition。
最后,我们定义一个Main类,在其main()方法中添加如下测试代码:
package chapter03.conditional;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionalConfig.class);
ListService listService = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name") + "系统下的列表命令为:" + listService.showListCmd());
context.close();
}
}
运行结果如下所示:
This is WindowsListService constructor
Windows 7系统下的列表命令为:dir
从运行日志可以看出,由于当前系统是Windows 7,我们声明的linuxListService bean并没有被装配。
3. 源码及参考
源码地址:https://github.com/zwwhnly/spring-action.git,欢迎下载。
汪云飞《Java EE开发的颠覆者:Spring Boot实战》
Craig Walls 《Spring实战(第4版)》
原创不易,如果觉得文章能学到东西的话,欢迎点个赞、评个论、关个注,这是我坚持写作的最大动力。
如果有兴趣,欢迎添加我的微信:zwwhnly,等你来聊技术、职场、工作等话题(PS:我是一名奋斗在上海的程序员)。
Spring入门(六):条件化的bean的更多相关文章
- (二)spring 高级装配-Condition -条件化的bean
Condition:满足某个特定条件的情况下创建bean 条件化配置bean: a:@Conditional 指定一个class ,它指明了通过条件对比的类.如果没有指定class则通过Condito ...
- Spring 梳理-profile与条件化定义bean
定义profile <beans> //root <beans profile="dev"> <bean id=.../> </beans ...
- 第3章—高级装配—条件化的Bean
条件化的Bean 通过活动的profile,我们可以获得不同的Bean.Spring 4提供了一个更通用的基于条件的Bean的创建方式,即使用@Conditional注解. @Conditional根 ...
- 【Java Web开发学习】Spring4条件化的bean
[Java Web开发学习]Spring4条件化的bean 转载:https://www.cnblogs.com/yangchongxing/p/9071960.html Spring4引入了@Con ...
- Spring入门(4)-注入Bean属性
Spring入门(4)-注入Bean属性 本文介绍如何注入Bean属性,包括简单属性.引用.内部Bean.注入集合等. 0. 目录 注入简单值 注入引用 注入内部Bean 装配集合 装配空值 使用命名 ...
- 002Conditional条件化创建bean
01.条件化配置bean @Bean @Conditional(MagicExistsCondition.class)---->条件化创建bean public MagicBean magicB ...
- Spring入门2. IoC中装配Bean
Spring入门2. IoC中装配Bean 20131125 前言: 上一节学习了Spring在JavaProject中的配置,通过配置文件利用BeanFactory和ApplicationConte ...
- Spring高级装配(二) 条件化的bean
如果你希望一个bean在特定的条件下才会出现: 应用的类路径下包含特定的库时才创建 只有当某个特定的bean也声明之后才会创建 某个特定的环境变量设定之后才创建某个bean 在Spring 4之前,很 ...
- Spring入门(二):自动化装配bean
Spring从两个角度来实现自动化装配: 组件扫描(component scanning):Spring会自动发现应用上下文中需要创建的bean. 自动装配(autowiring):Spring会自动 ...
随机推荐
- django基础知识之后台管理Admin站点:
Admin站点 通过使用startproject创建的项目模版中,默认Admin被启用 1.创建管理员的用户名和密码 python manage.py createsuperuser 然后按提示填写用 ...
- ORM----hibernate入门Demo(无敌详细版)
一.Hibernate(开放源代码的对象关系映射框架)简介: Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全 ...
- watch 和 computed
<template> <div class="hello"> <h1>{{ msg }}</h1> <h2>Essent ...
- SpringBoot 2.0.3 源码解析
前言 用SpringBoot也有很长一段时间了,一直是底层使用者,没有研究过其到底是怎么运行的,借此机会今天试着将源码读一下,在此记录...我这里使用的SpringBoot 版本是 2.0.3.RE ...
- Java中什么是type,它和class有什么关系?
看代码总能遇到关键字--type,对于type的概念不明白.翻译水平也有限,所以贴几个地址.自己先看着. https://stackoverflow.com/questions/16600750/di ...
- 关于int和integer
大家可以看一下下面这个java程序的运行结果 int k = 1; int l = 1; System.out.println(k == l); int a = 128; int b = 128; S ...
- 个人永久性免费-Excel催化剂功能第19波-Excel与Sqlserver零门槛交互-查询篇
对频繁使用Excel的高级应用的尝试用户来说,绕不过的一个问题Excel的性能问题,对于几万条数据还说得过去,上了10万行的数据量,随便一个函数公式的运算都是一个不小的负荷,有些上进一点的用户会往Ac ...
- 题解 P5367 【【模板】康托展开】
P5367 [模板]康托展开 感觉这题难度大概在绿题到蓝题之间qwq 一.洛谷日报[yummy]浅谈康托展开 如我想知道321是{1,2,3}中第几个小的数可以这样考虑 : 第一位是3,当第一位的数小 ...
- JVM调优之探索CMS和G1的物理内存归还机制
前言: 公司有一个资产统计系统,使用频率很低,但是要求在使用时查询速度快,因此想到做一些缓存放在内存中,在长时间没有使用,持久化到磁盘中,并对垃圾进行回收,归还物理内存给操作系统,从而节省宝贵资源给其 ...
- Spark学习之RDD
RDD概述 什么是RDD RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素可并行计算的集合 ...