前言
最近一直在搞公司各个应用国际化的内容,简单的运用可以看这篇文章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各一份,这样问题就发生了
- @Component 会把这个类进入Springboot中管理,如果出现多个相同名称的类,便会报错,当然也可以通过后面设定
name
属性,但是如果出现很多个模块,我每一次都要复制粘贴,每一次都要设定“唯一”的@Component 名字,显得很麻烦。 - 如果出现模块互相引用,但是你又不清楚依赖关系,输入
InternationalMsgUtil
就会出现多个提示方法。 - 复制粘贴操作太傻了。
- 假如后续有更新操作,每一个Util都需要进行Update操作,复杂度更高。
于是我,做了一个international-spring-boot-starter
包,依赖于Springboot初始化内容,这样做的好处是,只需要更改maven依赖,“哪里没有加在哪里”,基本上放入common或者core模块中即可
制作 international-spring-boot-starter