Scanning i18n properties without hard coding
2018-05-27 / modified at 2022-04-04 / 219 words / 1 mins
️This article has been over 2 years since the last update.

This guide will give you an introduce on how to auto scan properties files into MessageSource without hard coding file names in Java.

The message file may be complex with depth.

1
2
3
4
5
6
7
8
9
/src/main/resources/
----/i18n/
-------->msg1_zh_CN.properties
-------->msg1_en_US.properties
-------->msg1.properties
-------->detp2/msg2_zh_CN.properties
-------->detp2/msg2_en_US.properties
-------->detp2/msg2.properties
...

In the legacy way of MessageSource, we call setBasename with hard code.

1
2
3
4
5
6
7
8
9
10
11
12
@Configuration
public class I18nConfiguration {

@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
// ugly hard code here
messageSource.setBasename("classpath:/i18n/msg1","classpath:/i18n/detp2/msg2","classpath:/i18n/mesg3");
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}
}

Here is the solutino with Mybatis VFS API(It saved your time but break the cohesion)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Configuration
public class I18nConfiguration {

@Bean
public MessageSource messageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
try{
List<String> list = VFS.getInstance().list("i18n"); //classpath:/i18n dir
List<String> properties = list.stream()
.filter(s-> s.endWith(".properties"))
.map(s -> "classpath:" + s.replaceAll("_.*\\.properties", ""))
.distinct().toArray();
messageSource.setBasename(properties);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}catch (Exception e){
throw new BeanCreationException("scan failed", e);
}
}
}