前言

最近一直在搞公司各个应用国际化的内容,简单的运用可以看这篇文章i18n 国际化改造,期初我最开始写了一个InternationalMsgUtil,代码如下:

import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

/**
 * @Author hang.wang
 * @Date 2022/11/25 19:31
 */
@Component
public class InternationalMsgUtil {

    @Resource
    MessageSource messageSource;

    private static MessageSource staticMessageSource;

    @PostConstruct
    public void init() {
        staticMessageSource = messageSource;
    }

    public static String getMessage(String path) {
        return staticMessageSource.getMessage(path, null, LocaleContextHolder.getLocale());
    }

}
@PostConstruct的部分,只是为了把注入的messageSource实例赋值给staticMessageSource
因为这个类属于一个工具类,我想让他直接通过 InternationalMsgUtil.getMessage(String path); 就可以调用
但是在Springboot中,无法对static对象注入(@Autowired 或 @Resource 均不可以)
并且@PostConstruct依赖于Springboot,在此类进入Bean管理时,自动执行注解下的init方法

注入静态变量也可以这样做

public class InternationalMsgUtil {

    private static InternationalService internationalService;

    @Resource
    public void setInternationalService(InternationalService internationalService) {
        InternationalMsgUtil.internationalService = internationalService;
    }

    public static String getMessage(String path) {
        return internationalService.getMsg(path);
    }

}

改进

按照上面两个代码写一个Util工具类是没有问题的,也可以完美使用,那还有什么需要改进的呢?首先,在一个企业级项目中,可能会存在很多个module,也就是多个模块,他们之间可能会存在引用关系,也可能不存在,假如A模块和B模块相互独立,他们又都有一个parent,那么我就要把这个Util复制粘贴到A、B各一份,这样问题就发生了

  1. @Component 会把这个类进入Springboot中管理,如果出现多个相同名称的类,便会报错,当然也可以通过后面设定name属性,但是如果出现很多个模块,我每一次都要复制粘贴,每一次都要设定“唯一”的@Component 名字,显得很麻烦。
  2. 如果出现模块互相引用,但是你又不清楚依赖关系,输入InternationalMsgUtil就会出现多个提示方法。
  3. 复制粘贴操作太傻了。
  4. 假如后续有更新操作,每一个Util都需要进行Update操作,复杂度更高。
于是我,做了一个 international-spring-boot-starter 包,依赖于Springboot初始化内容,这样做的好处是,只需要更改maven依赖,“哪里没有加在哪里”,基本上放入common或者core模块中即可
制作 international-spring-boot-starter
最后修改:2023 年 01 月 10 日
如果觉得我的文章对你有用,请随意赞赏