笔记-Springboot Util工具类读取配置文件(yml properties)

GPT-4: 在Java中,一个典型的工具(Util)类通常包含一些静态方法,这些方法用于提供通用的、非特定于对象的功能。这些类通常被设计成不可实例化和不可继承的

public final class Util {
    @Value("${staticServer}")
    private static String staticServer; //静态资源服务器地址
    
    // 私有构造函数,防止实例化
    private MyUtils() {
        throw new AssertionError("No MyUtils instances for you!");
    }
    
    //拼接完整静态资源URL,如 https://static.server/images/cat.jpg
    public static String getStaticResourceURI(String prefix, String filename) {
        return staticServer + prefix + '/' + encodeUri(filename);
    }public static String encodeUri(String uri) {
        return UriUtils.encode(uri, StandardCharsets.UTF_8);
    }

编译!
运行!
Bomb!
好的,完犊子了,你猜这怎么着,staticServer == null
可怜 弱小 又无助
这不核理,为什么会这样呢,对静态成员的注入从技术上应该是可以实现的
不过静态成员并不属于实例对象,可能与IOC容器 & 依赖注入的理念不符,所以Springboot并不直接支持
辣怎办
但是这个需求很合理好吧,在工具类中用到配置文件中的键值
Pre
不过丑话说在前头,如果要想进行依赖注入,那么Util类必须是一个Bean,因为只有Bean才能被IOC容器管理
所以,Util的构造函数不能是私有的,还真就得开放给Springboot使用
总不能又要隐私,又要躺着把钱挣了吧(哪有这好事)
所以:

@Component //注册为Bean
public final class Util {
    //private MyUtils() { 公开啦!哭
    //    throw new AssertionError("No MyUtils instances for you!");
    //}
}
  1. 利用set方法注入
@Component
public final class Util {
    private static String staticServer; //静态资源服务器地址
    
    @Value("${staticServer}")
    public void setStaticServer(String staticServer) { //
        Util.staticServer = staticServer;
    }
    
    public static String getStaticResourceURI(String prefix, String filename) {
        return staticServer + prefix + '/' + encodeUri(filename);
    }
    ...
    }

把@Value写在非静态成员方法上,就可以正常被执行

然后在函数体里对static成员赋值,狸猫换太子
2. 利用@PostConstruct注解

@Component
public final class Util {
    @Value("${staticServer}")
    private String staticServer;
    private static Util INS;@PostConstruct // 在构造函数和依赖注入完成后执行;构造方法 > @Autowired > @PostConstruct,毕竟构造完成才能注入成员
    public void init() {
        INS = this; // 获取Bean实例,赋值给静态变量,方便static函数访问
    } // 容器管理的Bean默认是单例的,所以这里的INS是唯一的// 拼接完整静态资源URL,只对filename进行编码
    public static String getStaticResourceURI(String prefix, String filename) {
        return INS.staticServer + prefix + '/' + encodeUri(filename);
    }// 对uri进行编码,注意'/'也会被编码
    public static String encodeUri(String uri) {
        return UriUtils.encode(uri, StandardCharsets.UTF_8); //URLEncoder会把' '编码为'+'而非'%20'造成错误
    }
}

看到这个名字(@PostConstruct),不知道大家有没有想起什么
二叉树的后序遍历:PostOrder
诶,为什么都是Post,马萨卡
对喽,PostConstruct是在构造函数之后执行的,核理
由于执行顺序是:构造方法 > @Autowired > @PostConstruct
所以,执行@PostConstruct的时候,staticSever已经注入完成,不用担心,一切就绪
我们只要把IOC容器中的Util实例的this指针赋值给static变量INS即可(指针的赋值啊,问题不大)

  1. @ConfigurationProperties
@Component
@ConfigurationProperties
public final class Util {
    private static String staticServer;public void setStaticServer(String staticServer) {
        Util.staticServer = staticServer;
    }
}

这个其实本质上也是利用set方法进行注入的,所以并不违反规则

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值