我们先建实体类 Dragon.java :
/**
-
@Author JCccc
-
@Description
-
@Date 2021/08/11 9:55
*/
public class Dragon {
private String name;
private Integer age;
private String master = “JCccc”;
public Dragon(String name, Integer age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return “Dragon{” +
“name='” + name + ‘’’ +
“, age=” + age +
“, master='” + master + ‘’’ +
‘}’;
}
}
然后在MyBeanConfig.java 里面把这个bean创建丢到容器里:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
/**
-
@Author JCccc
-
@Description
-
@Date 2021/10/19 10:01
*/
@Configuration
public class MyBeanConfig {
@Bean
@Conditional(DragonCondition.class)
public Dragon createDragon() {
return new Dragon(“波伦加”,18);
}
}
可以看到,我这创建bean,使用了 @Conditional :
@Conditional(DragonCondition.class)
没错,这就是我给 这个Dragon实体类 自定义的创建前置条件 ,DragonCondition :
ps: DragonCondition 实现了 Condition接口, 然后重写了匹对方法mathces,写了一些判断逻辑,从配置文件中取值,看看龙珠颗数是否为7。
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;
import java.util.Objects;
/**
-
@Author JCccc
-
@Description 召唤神龙的条件
-
@Date 2021/10/19 10:03
*/
public class DragonCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
if (7 == Integer.parseInt(Objects.requireNonNull(context.getEnvironment().getProperty(“summon.dragon-ball”)))){
return true;
}
return false;
}
}
接下来,我们来测试一下,
我们在yml文件添加配置项:
summon:
dragon-ball: 7
然后到测试类里面简单写个测试方法,看看Dragon 这个bean是否能成功被创建 :
import com.elegant.testdemo.happy.Dragon;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class TestdemoApplicationTests {
@Autowired(required = false)
//Autowired 设置为false,允许注入的时候找不到的情况,不会报错
private Dragon dragon;
@Test
void contextLoads() {
System.out.println(dragon);
}
}
执行,可以看到,因为我们条件匹对符合,神龙bean能成功创建:
那么我们把配置里面的龙珠颗树参数改一下,改成 5 :
到这里,其实 基本的Condition 配合 @Conditional 注解的使用已经掌握了。
那么接下来,继续,我们开始玩一下这个派生注解:
@ConditionalOnBean:当容器中有指定Bean的条件下进行实例化。
@ConditionalOnMissingBean:当容器里没有指定Bean的条件下进行实例化。
@ConditionalOnClass:当classpath类路径下有指定类的条件下进行实例化。
@ConditionalOnMissingClass:当类路径下没有指定类的条件下进行实例化。
@ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
@ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
@ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
@ConditionalOnExpression:基于SpEL表达式的条件判断。
@ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
@ConditionalOnResource:当类路径下有指定的资源时触发实例化。
@ConditionalOnJndi:在JNDI存在的条件下触发实例化。
@ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。
接下来我挑选几个常用的细细说说,
@ConditionalOnProperty : 当指定的属性有指定的值时进行实例化。
也就是说,我们可以让某个bean创建时,进行 配置值的匹对,符合条件了才能正常创建。
实践环节
单值匹对
示例:
RoleInitializer 这个bean,如果想让它正常实例化,我们需要检测yml配置文件里面,app.public的值是否为 true :
yml配置文件我们添加配置值:
启动项目,可以看到这个bean是符合条件的成功实例化:
我们把yml的值改一下:
再启动项目,可以看到这个bean没有被实例化,因为不符合条件:
ps:到这,也许会有一些看官会有想法:
这样的使用注解去检测yml里面的值,跟我们直接拉去配置文件的值,写个if判断 不是一样吗?
答案: 看似一样,实则并不。 硬编码的概念。 实例化和没实例化的区别。 不多说。
还没完, 上面是 @ConditionalOnProperty比较简单的使用例子,单纯一个配置值的匹对。
接下来是多值匹对场景
示例 :
RoleInitializer 这个bean,如果想让它正常实例化,我们需要检测yml配置文件里面,app.public的值是否为 true 且 app.vip 的值 也为 true:
关系是 且 ,也就是AND ,同时符合的概念,我们可以这么写:
@ConditionalOnProperty(name={“app.public”,“app.vip”}, havingValue=“true”)
@ConditionalOnProperty的注解能够支撑的、常用的方式也就差不多这些,更多元化的匹对效果是无法支持的,例如我们想要 匹对条件值A 为 1 同时 B 为 2 ,这种情形就已经无法支撑了。
不过我们可以换个概念表达,变成 匹对条件值AB 为 12 .
而且再补充一点,目前@ConditionalOnProperty的使用都是 且 (AND) 关系,如果你要用OR的方式的条件,那么也是很 sorry,@ConditionalOnProperty 支撑不了。
除非我们使用文章一开始介绍的自定义condition,完全是ok的。
那么就只能用自定义condition去实现这些多条件的匹对场景了吗?
答案是 : 并不 ,接下来看@ConditionalOnExpression 注解。
@ConditionalOnExpression :基于SpEL表达式的条件判断。
也是可以用于对配置文件的属性做一些匹对条件,但是功能强大很多。
就基于上面说到的例子,我们如果需要匹对的条件是多值:
app.public 值为 true 且 app.vip 值为 high 时 ,才能正常实例化RoleInitializer这个bean。
那么使用@ConditionalOnExpression ,我们可以这么写:
@ConditionalOnExpression(“'KaTeX parse error: Expected 'EOF', got '&' at position 26: ….equals('high')&̲&{app.public:true}”)
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
总结
一般像这样的大企业都有好几轮面试,所以自己一定要花点时间去收集整理一下公司的背景,公司的企业文化,俗话说「知己知彼百战不殆」,不要盲目的去面试,还有很多人关心怎么去跟HR谈薪资。
这边给大家一个建议,如果你的理想薪资是30K,你完全可以跟HR谈33~35K,而不是一下子就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。
最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!
Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
就把自己的底牌暴露了出来,不过肯定不能说的这么直接,比如原来你的公司是25K,你可以跟HR讲原来的薪资是多少,你们这边能给到我的是多少?你说我这边希望可以有一个20%涨薪。
最后再说几句关于招聘平台的,总之,简历投递给公司之前,请确认下这家公司到底咋样,先去百度了解下,别被坑了,每个平台都有一些居心不良的广告党等着你上钩,千万别上当!!!
Java架构学习资料,学习技术内容包含有:Spring,Dubbo,MyBatis, RPC, 源码分析,高并发、高性能、分布式,性能优化,微服务 高级架构开发等等。
还有Java核心知识点+全套架构师学习资料和视频+一线大厂面试宝典+面试简历模板可以领取+阿里美团网易腾讯小米爱奇艺快手哔哩哔哩面试题+Spring源码合集+Java架构实战电子书。
[外链图片转存中…(img-mB9zRXsE-1713399729368)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!