spring对bean的高级装配之基于@Conditional条件化装配
上篇介绍了如何基于profile来条件化创建bean,spring会根据profile的激活状态来进行创建;这篇介绍如何基于spring4.0引入的@Conditional和Condition接口来更加完美的创建bean;
假设你希望一个或多个bean只有在应用的类路径下包含特定的库时才创建。或者我们希望某个bean只有当另外某个特定的bean也声明了之后才会创建。我们还可能要求只有某个特定的环境变量设置之后,才会创建某个bean。在Spring 4之前,很难实现这种级别的条件化配置,但是Spring 4引入了一个新的@Conditional注解,它可以用到带有@Bean注解的方法上。如果给定的条件计算结果为true,就会创建这个bean,否则的话,这个bean会被忽略。下面举例说明:
假设有一个名为MagicBean的类,我们希望只有设置了magic环境属性的时候,Spring才会实例化这个类。如果环境中没有这个属性,那么MagicBean将会被忽略。下面使用@Conditional注解条件化地配置MagicBean:
代码中给@Conditional注解传了一个 我们自己开发的MagicExistsCondition的class,MagicExistsCondition必须要实现Condition接口,因为@Conditional就是基于Condition接口来进行条件比对的,下面是Condition接口的关键代码:
可以看到此接口有一个matches方法.当其返回true就会创建带有@Conditional注解的bean。如果matches()方法返回false,将不会创建这些bean;所以我们的MagicExistsCondition只要实现这个方法就可以了,下面是MagicExistsCondition代码:
matches()方法很简单但功能强大。它通过给定的ConditionContext对象进而得到Environment对象,并使用这个对象检查环境中是否存在名为magic的环境属性。在本例中,属性的值是什么无所谓,只要属性存在即可满足要求。如果满足这个条件的话,matches()方法就会返回true。所带来的结果就是条件能够得到满足,所有@Conditional注解上引用MagicExistsCondition的bean都会被创建。如果magic这个属性不存在方法就会返回false从而不会创建这些bean;
下面记录下matches这个方法的两个强大的参数ConditionContext和AnnotatedTypeMetadata
一、ConditionContext
关键源码:
通过ConditionContext,我们可以做到如下几点:
1、借助getRegistry()返回的BeanDefinitionRegistry检查bean定义;
2、借助getBeanFactory()返回的ConfigurableListableBeanFactory检查bean是否存在,甚至探查bean的属性;
3、借助getEnvironment()返回的Environment检查环境变量是否存在以及它的值是什么;
4、读取并探查getResourceLoader()返回的ResourceLoader所加载的资源;
5、借助getClassLoader()返回的ClassLoader加载并检查类是否存在。
二、AnnotatedTypeMetadata(能够让我们检查带有@Bean注解的方法上还有什么其他的注解)
关键源码:
借助isAnnotated()方法,我们能够判断带有@Bean注解的方法是不是还有其他特定的注解。借助其他的那些方法,我们能够检查@Bean注解的方法上其他注解的属性。
需要 注意的是,从spring4开始,上篇提到@Profile注解的实现原理也是基于@Conditional和Condition的实现了,下面是Profile的源码:
可以看到@Profile提供了ProfileCondition来实现了Condition接口,下面我们看下ProfileCondition是如何实现matches方法的:
我们可以看到,ProfileCondition通过AnnotatedTypeMetadata得到了用于@Profile注解的所有属性。借助该信息,它会明确地检查value属性,该属性包含了bean的profile名称。然后,它根据通过ConditionContext得到的Environment来检查[借助acceptsProfiles()方法]该profile是否处于激活状态
spring对bean的高级装配之基于@Conditional条件化装配的更多相关文章
- 【10分钟学Spring】:@Profile、@Conditional实现条件化装配
根据不同的环境来装配不同的bean 企业级开发中,我们一般有多种环境,比如开发环境.测试环境.UAT环境和生产环境.而系统中有些配置是和环境强相关的,比如数据库相关的配置,与其他外部系统的集成等. 如 ...
- spring对bean的高级装配之profile机制
最近在读spring实战一书,个人感觉内容通俗易懂,学到了一些之前并不知道的知识,于是打算在博客里记录一下这些知识点便于后期记忆: 今天要记录的就是spring的条件化创建bean,针对条件化创建be ...
- spring中bean的高级属性之list, set, map以及props元素(含举例)
转自:http://qingfeng825.iteye.com/blog/144704 list, set, map和props元素分别用来设置类型为List,Set,Map和Propertis的属性 ...
- 面试阿里,字节,美团必看的Spring的Bean管理详解
IOC容器 工厂只负责创建对象,而Spring当然不仅仅是一个对象工厂,其核心是一个对象容器,其具备控制反转的能力,所以也称为IOC容器. 帮助我们存放对象,并且管理对象,包括:创建.销毁.装配,这样 ...
- Spring高级装配(二) 条件化的bean
如果你希望一个bean在特定的条件下才会出现: 应用的类路径下包含特定的库时才创建 只有当某个特定的bean也声明之后才会创建 某个特定的环境变量设定之后才创建某个bean 在Spring 4之前,很 ...
- (二)spring 高级装配-Condition -条件化的bean
Condition:满足某个特定条件的情况下创建bean 条件化配置bean: a:@Conditional 指定一个class ,它指明了通过条件对比的类.如果没有指定class则通过Condito ...
- Spring中Bean的配置:基于XML文件的方式
Bean的配置一共有两种方式:一种是基于XML文件的方式,另一种是基于注解的方式.本文主要介绍基于XML文件的方式 <bean id="helloWorld" class=& ...
- 【Spring】Spring的bean装配
前言 bean是Spring最基础最核心的部分,Spring简化代码主要是依赖于bean,下面学习Spring中如何装配bean. 装配bean Spring在装配bean时非常灵活,其提供了三种方式 ...
- spring学习总结——高级装配学习二(处理自动装配的歧义性)
我们已经看到如何使用自动装配让Spring完全负责将bean引用注入到构造参数和属性中.自动装配能够提供很大的帮助.不过,spring容器中仅有一个bean匹配所需的结果时,自动装配才是有效的.如果不 ...
随机推荐
- 导航栏中各按钮在点击当前按钮变色其他按钮恢复为原有色的实现方法(vue、jq、原生js)
一.vue如何实现? 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset= ...
- jfinal afterJFinalStart中执行长久循环操作的解决方案:创建新线程
很多时候,需要在jfinal中afterJFinalStart方法中,写一些需要一直循环运行的程序,做一些循环操作.但是在afterJFinalStart中,执行时间过长的话,会导致整个站点启动超时. ...
- MySQL 8.0.12 基于Windows 安装教程(超级详细)
MySQL 8.0.12 基于Windows 安装教程(超级详细) (一步一步来,装不了你找我!) 本教程仅适用Windows系统,如果你原本装了没装上,一定要先删除原本的数据库,执行:mysqld ...
- LCSS最长公共子序列算法
0.论文基本介绍以及相关内容 分析移动用户位置的相似性,提取移动用户的相似路径在出行路径预测.兴趣区域发现.轨迹聚类.个性化路径推荐等领域具有广泛的应用. 重点:利用移动用户定位数据找到合适轨迹的表示 ...
- NPM 报错--fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module
fs: re-evaluating native module sources is not supported. If you are using the graceful-fs module 解决 ...
- JAVA写接口傻瓜(%)教程(五)
今天主要说一下在URL 中使用?传值的问题.在显式的使用get方法获取特点数据时,一般会通过?传递参数值,sevlert根据参数在数据库中对应的查找内容.所以,SQL语句需要拼接,要加上后面的参数.参 ...
- JAVA写接口傻瓜(!)教程(二)
接上一篇 3.数据库SQL sever配置 理论上来说,java web项目连接什么数据库都行,但是我电脑上SQL sever用了三年了,各种操作都比较熟悉,所以也懒得再用My SQL.想用My SQ ...
- redis 持久化共享 Session
https://docs.microsoft.com/zh-cn/azure/redis-cache/cache-aspnet-session-state-provider
- 10ci
- 用docker搭建python项目运行环境
Docker Hub镜像加速器 安装docker: curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-eng ...