历史文章(累计400+篇文章)
SpringBoot/Spring扩展点系列之FactoryBean让你不在懵逼 - 第435篇
SpringBoot/Spring扩展点系列之SmartInitializingSingleton - 第436篇
扩展点系列之CommandLineRunner和ApplicationRunner实现缓存预热 - 第437篇
SpringBoot/Spring扩展点系列之初始化和销毁的3种办法 - 第438篇
服务信息上报+记录请求信息+监听项目运行状态还能这么玩「扩展点系列」- 第440篇
悟纤:师傅,我发现了一个奇怪的事情。
师傅:来,给为师分享一下。
悟纤:曾几何时,不知不觉成为了我们讨厌的样子。
师傅:此话怎讲?
悟纤:曾几何时,我们讨厌别人抽烟,但我们却抽烟了;曾几何时,我们讨厌别人乱扔垃圾,我们却随意仍了;曾几何时,我们觉得打游戏的人不求上进,但我们自己却迷上了游戏。曾几何时,那些我们讨厌的人事物,却成了自己~
师傅:师傅,只能说,这就是成长吧~不曾经历,谈何懂得,不曾拿起,谈何放下。当然也不是所有的事情都要去经历,有些事情经历了那可能会万劫不复。
师傅:事情不是只有两面性,非黑即白,有些时候要去寻找中间的状态。有些事情,也不是没有绝对的对与错。
悟纤:师傅,我懂了,凡事不沉迷,不过度,或许这个事情,就不是坏事。
师傅:嗯嗯,是这么一个理~ 但这个度很难把握!如果你控制不住,那么就远离。
悟纤:师傅,我知道了,还是赶紧学习吧,强大自身才是硬道理。
导读
对于配置文件application.properties或者application.yml中的配置属性,希望封装成一个Java对象。耶,这个看起来很简单呢,@Value不就可以实现了吗?那如果我在加一个条件,就是这个属性是静态属性呢?对于这样的情况具体怎么玩呢?这一节我们就使用之前学习的扩展点来带大家一探究竟。
👇🏻👇🏻👇🏻扩展点实战系列:
01.《观察者模式实际应用场景「扩展点实战系列」》
02.《服务信息上报+记录请求信息+监听项目运行状态还能这么玩🐴「扩展点实战系列」》
03.《配置类信息赋值为Java静态变量「扩展点实战系列》」》
04. 「待拟定」《扩展RestTemplate让其具备负载均衡能力「扩展点实战系列」》
一、配置属性封装成一个Java对象
需求描述:对于配置文件application.properties或者application.yml中的配置属性,封装成一个Java对象。
首先先来看下这个基本的需求要怎么操作?
接下来的代码随便一个SpringBoot项目上就可以进行编码,这里的话,我们直接在上一节的项目spring-boot-applicationlistener-example进行编码。
1.1 配置文件配置属性
首先在配置文件application.properties(.yml)添加属性:
author.name = 悟纤
author.official-accounts = SpringBoot
author. = @SpringBoot公众号版权所有copyright
1.2 将属性封装成一个Java对象
将属性封装成一个Java对象,这里的话,回顾一下主要有这么几种方式:
(1)@ConfigurationProperties和@Configuration配合使用。
(2)@ConfigurationProperties和@EnableConfigurationProperties
配合使用。
(3)@ConfigurationProperties和@ConfigurationPropertiesScan。
(4)@Value和@Configuration/@Component。
(5)@PropertySource
->5种读取配置文件的方式,你了解了吗?公众号「SpringBoot」回复关键词[380],查看文章《Spring Boot居然有这么5种读取配置文件的方式,你居然还不知道?- 第380篇》,文章地址如下:
https://mp.weixin.qq.com/s/1rhT2wpIIrwMwshPchgo5Q
…
这里我们直接使用@Value进行使用:
package com.kfit.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Author
* @author 悟纤「公众号SpringBoot」
* @date 2022-08-29
* @slogan 大道至简 悟在天成
*/
@Configuration
public class Author {
@Value(("${author.name}"))
private String name;
@Value(("${author.official-accounts}"))
private String officialAccounts;
@Value(("${author.copyright}"))
private String copyright;
@Override
public String toString() {
return "Author{" +
"name='" + name + '\'' +
", officialAccounts='" + officialAccounts + '\'' +
", copyright='" + copyright + '\'' +
'}';
}
}
1.3 使用Author进行测试
将Author注入到一个类进行测试一下:
@Autowired
private Author author;
@RequestMapping("/author")
public String author(){
System.out.println(author);
return "OK.";
}
访问地址:
http://127.0.0.1:8080/author
查看控制台的打印:
信息是注入了,但芭比Q了,还乱码了,那么乱码是怎么回事呢?这里不重复说明了
->乱码怎么回事,公众号「SpringBoot」回复关键词[384],查看文章《SpringBoot使用@Value读取.properties中文乱码及解决方法 - 第384篇》,文章地址如下:
https://mp.weixin.qq.com/s/U1zXMaFzhu-2siTuHx_inw
二、配置属性封装成一个Java静态变量
需求描述:在上面的需求上在加一个条件,就是这个属性是静态属性呢?对于这样的情况具体怎么玩呢?
2.1 直接添加为static
我们的第一个思路肯定是直接在属性上添加为static,然后设置为public方法,去掉Author类的get和set方法:
package com.kfit.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Author
* @author 悟纤「公众号SpringBoot」
* @date 2022-08-29
* @slogan 大道至简 悟在天成
*/
@Configuration
public class Author {
@Value(("${author.name}"))
public static String name;
@Value(("${author.official-accounts}"))
public static String officialAccounts;
@Value(("${author.copyright}"))
public static String copyright;
}
2.2 调用方式
现在是static的方式了,那么就可以直接类+属性进行访问了呗:
@RequestMapping("/author")
public String author(){
System.out.println(Author.name+"--"+Author.officialAccounts+"-"+Author.copyright);
return "OK.";
}
访问结果:
这个结果肯定不是我们想要的,那么要怎么破呢?
有两种方案:
(1)实现接口InitializingBean的afterPropertiesSet方法。
(2)配合@ConfigurationProperties加个set方法。
2.3 方案一:实现接口InitializingBean
复习下InitializingBean:在Spring Bean初始化后自动做一些事情,就可以使用InitializingBean。当然其它的方式,具体可以参考之前的文章《扩展点系列之初始化之@PostConstruct、init-method、InitializingBean - 第434篇》
具体的代码如下:
package com.kfit.config;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Author
* @author 悟纤「公众号SpringBoot」
* @date 2022-08-29
* @slogan 大道至简 悟在天成
*/
@Configuration
public class Author implements InitializingBean {
@Value(("${author.name}"))
private String name1;
@Value(("${author.official-accounts}"))
private String officialAccounts1;
@Value(("${author.copyright}"))
private String copyright1;
public static String name;
public static String officialAccounts;
public static String copyright;
@Override
public void afterPropertiesSet() throws Exception {
name = this.name1;
officialAccounts = this.officialAccounts1;
copyright = this.copyright1;
}
}
测试代码:
@RequestMapping("/author")
public String author(){
System.out.println(Author.name+"--"+Author.officialAccounts+"-"+Author.copyright);
return "OK.";
}
访问结果:
说明:这里为了看起来舒服点,我把配置文件的author.name修改成了英文。
2.4 直接在@Value的基础上添加set方法
在类Author上添加相应属性的set/get方法,不管方法是否是静态的,测试结果值都是null。说明不能这么玩。
2.4 方案二:配合@ConfigurationProperties加个set方法
在研究的过程中,发现了一个更好的方案,就是使用@ConfigurationProperties。
要使用@ConfigurationProperties需要添加一个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
然后修改类Author:
package com.kfit.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* Author
* @author 悟纤「公众号SpringBoot」
* @date 2022-08-29
* @slogan 大道至简 悟在天成
*/
@Configuration
@ConfigurationProperties(prefix = "author")
public class Author {
public static String name;
public static String officialAccounts;
public static String copyright;
public String getName() {
return name;
}
public void setName(String name) {
Author.name = name;
}
public String getOfficialAccounts() {
return officialAccounts;
}
public void setOfficialAccounts(String officialAccounts) {
Author.officialAccounts = officialAccounts;
}
public String getCopyright() {
return copyright;
}
public void setCopyright(String copyright) {
Author.copyright = copyright;
}
}
测试类:
@RequestMapping("/author")
public String author(){
System.out.println(Author.name+"--"+Author.officialAccounts+"-"+Author.copyright);
return "OK.";
}
访问结果:
So wonderful !
总结
配置类信息赋值为Java静态变量除了本文介绍的如下两种方案:
(1)实现接口InitializingBean的afterPropertiesSet方法。
(2)配合@ConfigurationProperties加个set方法。
还有其它的方案,比如还可以配合类Environment获取到属性,在某个扩展点注入到静态变量,这里注入扩展点的地方就多了,前面几节介绍的好几个扩展点都是可以满足的。
下节精彩预告:
在Spring Web中有一个简化网络请求的类RestTemplate,文档中的英文描述:
但这个类默认情况下不具备负载均衡的,那么怎么利用Spring扩展点,让其具备负载均衡能力呢?如果你知道了如何实现了,那么Ribbon的原理,你也就知道了百分六七十。
具体怎么实现,且听下回分解。
我就是我,是颜色不一样的烟火。
我就是我,是与众不同的小苹果。
à悟空学院:https://t.cn/Rg3fKJD
学院中有Spring Boot相关的课程!点击「阅读原文」进行查看!
SpringBoot视频:http://t.cn/A6ZagYTi
SpringBoot交流平台:https://t.cn/R3QDhU0
SpringSecurity5.0视频:http://t.cn/A6ZadMBe
ShardingJDBC分库分表:http://t.cn/A6ZarrqS
分布式事务解决方案:http://t.cn/A6ZaBnIr
JVM内存模型调优实战:http://t.cn/A6wWMVqG
Spring入门到精通:https://t.cn/A6bFcDh4
大话设计模式之爱你:https://dwz.cn/wqO0MAy7