配置类信息赋值为Java静态变量「扩展点实战系列》」- 第441篇

发布于:2023-01-04 ⋅ 阅读:(319) ⋅ 点赞:(0)

历史文章(累计400+篇文章)

国内最全的Spring Boot系列之一

国内最全的Spring Boot系列之二

国内最全的Spring Boot系列之三

国内最全的Spring Boot系列之四

国内最全的Spring Boot系列之五》

SpringBoot/Spring扩展点系列之FactoryBean让你不在懵逼 - 第435篇

SpringBoot/Spring扩展点系列之SmartInitializingSingleton - 第436篇

扩展点系列之CommandLineRunner和ApplicationRunner实现缓存预热 - 第437篇

SpringBoot/Spring扩展点系列之初始化和销毁的3种办法 - 第438篇

观察者模式实际应用场景「扩展点实战系列」- 第439篇

服务信息上报+记录请求信息+监听项目运行状态还能这么玩「扩展点系列」- 第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 = SpringBootauthor. = @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 大道至简 悟在天成 */@Configurationpublic 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注入到一个类进行测试一下:

@Autowiredprivate 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 大道至简 悟在天成 */@Configurationpublic 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 大道至简 悟在天成 */@Configurationpublic 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


网站公告

今日签到

点亮在社区的每一天
去签到