SpringBoot复习:3(@Conditional)
@Conditional
条件装配:满足@Conditional指定的条件时,则进行组件注入
@Conditional注解下面包含许多注解,如下图:
这些注解各有各的功能,这里挑几个来记录一下。
@ConditionalOnBean注解
个人理解:当该注解标注的方法或类有相应的组件时,才注册为组件,否则就不注册为组件。
看一下@ConditionalOnBean的源码,可以初步了解它的用法
在方法上使用
测试代码:
配置类
为了测试这里我把配置类中pet01方法的@Bean注解注释掉
@Configuration
public class MyConfig {@ConditionalOnBean(name = "cat")//当容器中有名为tom的组件的时候,下面的方法才注册为组件@Beanpublic User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}//@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
在主程序输出测试结果:
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import com.gcl.demo1helloworld.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;@SpringBootApplication(scanBasePackages="com.gcl")
public class Demo1HelloworldApplication {public static void main(String[] args) {//返回IOC容器ConfigurableApplicationContext context = SpringApplication.run(Demo1HelloworldApplication.class, args);//判断容器中是否包含user01这个组件boolean user = context.containsBean("user01");System.out.println("组件中包含user01?"+user);}
}
结果:
结果分析:
可以看到,此时容器中并没有user01这个组件了。
在类上使用
测试代码:
配置类:
/*** @author:小关同学爱吃汉堡* @date: 2021/4/5 17:44*/
@Configuration
@ConditionalOnBean(name="tom")
public class MyConfig {@Beanpublic User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
主程序测试:
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import com.gcl.demo1helloworld.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;@SpringBootApplication(scanBasePackages="com.gcl")
public class Demo1HelloworldApplication {public static void main(String[] args) {//返回IOC容器ConfigurableApplicationContext context = SpringApplication.run(Demo1HelloworldApplication.class, args);//检查容器中是否有下列组件boolean config = context.containsBean("myConfig");System.out.println("组件中包含config?"+config);boolean user = context.containsBean("user01");System.out.println("组件中包含user01?"+user);boolean cat = context.containsBean("cat");System.out.println("组件中包含cat?"+cat);}
}
结果:
我们可以发现,在配置类本身被否决为组件的情况下,配置类下面的所有配置都不生效了
@ConditionalOnMissingBean注解
个人理解:当给定的在bean不存在时,则实例化当前Bean。
再来看一下它的源码,如下图:
@ConditionalOnMissingBean注解作用在@bean定义上,在容器加载它作用的bean时,检查容器中是否存在目标类型(ConditionalOnMissingBean注解里面的值)的bean了,如果存在这跳过原始bean的BeanDefinition加载动作。
在方法上使用
在方法上使用时存在一些坑,让我困惑了好久
当@ConditionalOnMissingBean注解使用name属性时会有一些问题,如下:
配置类
import ch.qos.logback.core.db.DBHelper;
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;/*** @author:小关同学爱吃汉堡* @date: 2021/4/5 17:44*/
@Configuration
public class MyConfig {@Bean//我们在这里使用@ConditionalOnMissingBean注解//按理说,当容器中有名为user02的组件的时候,下面的方法就不会注册为组件@ConditionalOnMissingBean(name = "user02")public User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}@Beanpublic User user02(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
在主程序测试:
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import com.gcl.demo1helloworld.config.MyConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;@SpringBootApplication(scanBasePackages="com.gcl")
public class Demo1HelloworldApplication {public static void main(String[] args) {//返回IOC容器ConfigurableApplicationContext context = SpringApplication.run(Demo1HelloworldApplication.class, args);boolean config = context.containsBean("myConfig");System.out.println("组件中包含config?"+config);boolean user01 = context.containsBean("user01");System.out.println("组件中包含user01?"+user01);boolean user02 = context.containsBean("user02");System.out.println("组件中包含user02?"+user02);boolean cat = context.containsBean("cat");System.out.println("组件中包含cat?"+cat);}
}
结果:
这结果跟我们想的不太一样啊,user01那里按理说应该是false的,这什么情况???
问过身边的大佬之后,得出一个很草的结论:
这是一个组件创建顺序的问题,因为@ConditionalOnMissingBean(name = “user02”)执行之前,容器里面还没有名叫user02这个组件…所以user01组件总会被创建。
正确的使用姿势如下:
配置类:
import ch.qos.logback.core.db.DBHelper;
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;/*** @author:小关同学爱吃汉堡* @date: 2021/4/5 17:44*/
@Configuration
public class MyConfig {@Bean//@ConditionalOnMissingBean(name = "user02")//一般来说在这里使用@ConditionalOnMissingBean注解,//当容器中有名为user02的组件的时候,下面的方法不会注册为组件//但是,这里有一个执行顺序的问题,当执行这条语句的时候,//下面的user02组件还未注册,所以下面的方法是一定会被注册为组件的public User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean@ConditionalOnMissingBean(name = "user01")//当user01这个组件存在时,下面的方法不注册为组件public User user02(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
主程序代码不变
结果:
这时输出的结果跟我们预期的一致了,user02没有被放到容器里面。
当然,如果我们使用value属性判断时,则不会出现上述的问题,如下:
配置类
import ch.qos.logback.core.db.DBHelper;
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;/*** @author:小关同学爱吃汉堡* @date: 2021/4/5 17:44*/
@Configuration
public class MyConfig {@Bean@ConditionalOnMissingBean(value = User.class)public User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}@Beanpublic User user02(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
主程序代码不变
结果:
这时候我们发现user01没有被放入到容器中
在类上使用
在类上使用的话,不能使用该类里面注册的组件作为判断条件,不然条件总是为真,如下:
配置类
import ch.qos.logback.core.db.DBHelper;
import com.gcl.demo1helloworld.bean.Pet;
import com.gcl.demo1helloworld.bean.User;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;/*** @author:小关同学爱吃汉堡* @date: 2021/4/5 17:44*/
@Configuration
@ConditionalOnMissingBean(name = "cat")//条件装配
public class MyConfig {@Beanpublic User user01(){User user = new User("张三",19);user.setPet(pet01());return user;}@Beanpublic User user02(){User user = new User("张三",19);user.setPet(pet01());return user;}@Bean("cat")public Pet pet01(){return new Pet("cat");}
}
主程序代码同上
结果:
相关文章:

HDU——1106排序(istringstream的使用、STLvector练习)
排序 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 46057 Accepted Submission(s): 13221 Problem Description输入一行数字,如果我们把这行数字中的‘5’都看成空格,那么就得到一行用…

AssertValid函数学习
转自http://tsitao.blog.163.com/blog/static/29795822006914105840496/ VC的调试中,AssertValid和Dump函数的应用 CObject::AssertValid 成员函数提供对对象内部状态的运行时检查。虽然从 CObject 派生类时不须要重写 AssertValid,但能够通过重写使您的…
数值分析第一次作业-牛顿迭代法求解二元非线性方程组
1、问题 求解如下方程组: 2、算法 3、代码实现 # *coding:utf-8 * import math delta 5e-6 ;eps 1e-6 x0 1;y0 1 er 1;k 0 def z(x,y):return math.sin(x*y)*math.exp(-0.1*(x**2y**2x*y2*x)) def f(x,y):return y*math.cos(x*y)-0.1*(2*xy2)*math.sin(x*y) def g(x,y…

Maya制作风格化的女性跑步动画学习教程
时长:2h 11m |视频:. MP4 1280720,30 fps(r) |音频:AAC,48000 Hz,2ch |大小解压后:1.56 GB 含参考素材 流派:电子学习|语言:英语中英文字幕(根据原英文字幕机译更准确) 通过在Autodesk Maya中提供专业外观…

安卓手机抓包实战
最近因为要做一个项目,所以需要对手机给家电发送的请求进行抓取,于是上网找了许多教程,但都不怎么理想,最终经过两个晚上的艰辛奋斗,终于让我找到了方法抓取到了手机发送的请求,写一篇博客记录一下这个过程…

导入drupal中文语言包
http://lugir.com/book/export/html/399转载于:https://www.cnblogs.com/qinqiu/p/5174062.html

JavaScript引擎大战:Google提出StrongMode和SoundScript议案,增强V8性能
JavaScript 引擎性能大战硝烟迷漫,Chrome V8 引擎团队宣布了一个新的计划,在这个计划里他们介绍了两个新的虚拟机概念:强化模式(StrongMode)和强化脚本(StrongScript)。\\强化模式是 ES5 严格模…

数值分析第三次作业-常微分方程的数值解法
一、欧拉方法 二、修正的欧拉方法 2.1.梯形公式 将问题(*)的解表成积分形式,用数值积分方法离散化。例如,对微分方程

SYNCHRO 4D可视化调度学习教程 SYNCHRO 4D: Visual Scheduling
MP4 |视频:h264,1280720 |音频:AAC,44.1 KHz,2 Ch 技能水平:初级|流派:电子学习|语言:英语中英文字幕(根据原英文字幕机译更准确) |时长:3h 14m |大小:1.36 GB 含课程练习文件 课程获取:SYNCHR…

SpringBoot复习:4(@ImportResource)
ImportResource注解 作用:这个注解可以用来导入Spring的配置文件(bean.xml文件)。 适用场景: 可以试想一下这样一个场景,老板要你将原来的Spring项目改成SpringBoot项目,原项目底下有一大堆的bean.xml文件…

YTU 2723: 默认参数--求圆的面积
2723: 默认参数--求圆的面积 时间限制: 1 Sec 内存限制: 128 MB提交: 206 解决: 150题目描述 根据半径r求圆的面积, 如果不指定小数位数,输出结果默认保留两位小数。 部分代码已给定如下,只需要提交缺失的代码。 #include <iostream> #include <iomanip&…

jmeter内存溢出处理方式记录
方法一: 使用jmeter进行压力测试时 遇到一段时间后报内存溢出outfmenmory错误,导致jmeter卡死了,先尝试在jmeter.bat中增加了JVM_ARGS"- Xmx2048m -Xms2048m -Xmn256m -XX:PermSize128m -Xss256k",但结果运行时间增加了…

支持向量机学习笔记1
1、支持向量机是一种二类分类模型。它的模型基本定义是特征空间上间隔最大的线性分类器。 2、核函数的引入,使得支持向量机可以进行非线性分类。 3、支持向量机也可以完成多类别分类(将在后面介绍) 4、支持向量机的学习策略为间隔最大化&a…

C4D入门学习教程
MP4 |视频:AVC,1280720 30 fps |音频:AAC,48 KHz,2 Ch |时长:2h 12m 语言:英语中英文字幕(根据原英文字幕机译更准确)|大小解压后:560M C4D是一个有抱负的运动图形艺术家和设计师的重要工具。借助C4D&#…

SpringBoot复习:5(配置绑定)
配置绑定 在SpringBoot中我们如何读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用呢? 我们可以使用以下两种方式来实现。 方法一:ConfigurationPropertiesComponent 第一种方法,我们可以使用C…
是男人就下100层【第五层】——2048游戏从源代码到公布市场
上一篇《是男人就下100层【第五层】——换肤版2048游戏》中阳光小强对2048游戏用自己的方式进行了实现,并分享了核心源码,这一篇阳光小强打算将该项目的全部源码公开并结合这个实例在这篇文章中介绍一下怎样加入广告和实现分享功能。终于执行效果例如以下…

zabbix菜单出现问号乱码问题
zabbix菜单出现问号乱码问题 安装后zabbix,设置成中文后,发现菜单出现了好多的乱码,google之后才知道这与zabbix数据库字符集设置有关。查看当前的默认字符集:mysql> show create database zabbix;---------------------------…

什么是Closed-form solution?
最近看论文,讨论微分方程解时遇到closed-form solution概念,上网检索,找到一个较浅显易懂的解释如下。 与工学院所学的微分方程不同的是,工学院的学生一般都是学如何把特定的微分方程的解用基本函数(例如多项式、三角函…

c4d中的3D插图制作视频教程 Skillshare – 3D Illustration in Cinema 4D
技能分享——C4D的3D插图 教程大小解压后:1.33G 1920X1080 mp4 语言:英语中英文字幕(根据原英文字幕机译更准确) C4D是众所周知的平易近人的软件,也是进入3D艺术梦幻世界的理想门户。 加入马特的这个课程,…

SpringSecurity学习:1(第一个SpringSecurity项目)
此博客是记录自己学习过程的记录 第一个SpringSecurity项目 导入依赖 详细的步骤我就不多说了,使用IDEA创建过SpringBoot项目的人一般都能看懂。 这一步我们可以在使用IDEA创建SpringBoot项目的时候完成,如下图: 在创建SpringBoot项目时&a…

使用Struts2标签遍历集合
遍历Map<String,Object>遍历Map<Stirng,List<Student>>遍历List<Map<String,Student>>Student.java package action;public class Student {private Long sid;private String name;public Student() {// TODO Auto-generated constructor stub}p…

TortoiseGit的使用详解
然后A修改了,A想上传代码,发现冲突了,原因是A依靠的是1版本的代码进行了修改,而此时远程仓库的代码是2版本,这样当然会产生冲突。当从远程仓库拉取代码时,代码会直接拉取到工作区,然后我们要添加、提交,然后才可以把拉取的代码放入本地仓库,本地仓库的代码可以通过推送,推送到远程仓库,这是一个大循环。解决冲突的办法就是,先把远程仓库的2版本的代码进行拉取,然后TortoiseGit会列出冲突的文件代码,然后自己手动解决、选择自己需要的代码,右键选择解决冲突,最后再重新上传就可以了。点击拉取,可以下载文件。

Java的System.out.println()深入解析理解
语句来输出信息,从开始学习Java就知道用它来输出Hello World,没有深究其实现原理,现在查阅文档、源代码后记录一下。方法进行字符流输出,只是整个过程封装了许多方法来支持各种类型的变量、以及自动初始化等,使得用户能够方便快捷在控制台打印数据。变量进行了初始化,让它指向控制台,于是就可以直接使用了。的,因此即使程序中没有手动导入,也可访问到。由C/C++实现,这里只是一个接口,在。修饰的,根据Java语法,它只能调用。方法重载,因此可输出多种类型的数据。接着看,在构造方法中,先是初始化了。

第一次作业,针对软件工程这门课程提出五个疑问。
1、如果对于不爱好计算机的同学来说学习软件工程的意义大吗,有多大? 2、软件工程的知识面那么广,如果才能系统有效的将它学好? 3、软建工程这门课是否有点纸上谈兵了? 4、软件工程是衣门很枯燥的学科,我们怎…

matlab2013 a/b 找不到vs2013 c++ 编译器 解决方案
64-bit Matlab 解压附件后,放到 C:\Program Files\MATLAB\R2013a\bin\win64\mexopts32-bit Matlab 解压附件后,放到 C:\Program Files\MATLAB\R2013a\bin\win32\mexopts点我下载附件 原文出处:http://kaba.hilvi.org/homepage/blog/vs_201…

C4D运动图形基本训练学习教程
MP4 |视频:h264,1280720 |音频:AAC,44.1 KHz,2 Ch 技能水平:初级|语言:英语中英文字幕(根据原英文字幕机译更准确) |持续时间:3h 1m |大小解压后:1.7 GB 含课程练习文件 C4D继续作为3D艺术家的行业标准解决…

linux快捷上传下载文件
借助securtCRT,使用linux命令sz可以很方便的将服务器上的文件下载到本地,使用rz命令则是把本地文件上传到服务器 其中,对于sz和rz的理解与记忆我用了如下的方法(因为很多时候容易搞混):sz中的s意为send&…

Java多线程复习:3(在操作系统中查看和杀死进程线程)
此博客是记录自己学习过程的记录,仅做参考 Windows下查看和杀死进程线程 查看所有进程 tasklist 查看指定关键字的进程 tasklist | findstr 关键字 Java程序运行的时候都是通过java.exe来运行的,所以想要查看Java程序运行的详情的话必须使用jdk自带的命…

Adt 配置注释模板
点击Window->Preferences->Java->Code Style->Code Templates,如下图所示: 选中,点击右侧的Edit进行编辑。

解决Attempt to execute SCRIPT mexLasso as a function
Attempt to execute SCRIPT mexLasso as a function: Error in selectFeature (line 22)w mexLasso(L, A, param);Error in demo (line 62)P selectFeature(AA_pos, AA_neg, paramSR); % feature selection 遇到这个问题一般是因为名为mexLasso的文件与…