美文网首页
spring国际化

spring国际化

作者: 念䋛 | 来源:发表于2022-07-08 14:20 被阅读0次

Springboot 多语
spring多语的使用,需要将名称为messageSource的bean放到ioc容器中,可以使用配置文件或者数据库的方式实现多语
1.基于配置文件的方式
Server层

@Service
public class ServiceTest implements ApplicationContextAware { //用autowired直接从容器中获取也可以
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
    public String message() {
        //name 是多语的key  第三个参数是获取那个多语文件 如果是null 默认为 zh_CN
        //org.springframework.context.support.AbstractMessageSource.getMessageInternal  locale = Locale.getDefault(); 默认的返回值 zh_CN
        String message = applicationContext.getMessage ("name", null, null);
        String messagePersonalIntroduction = applicationContext.getMessage ("personal_introduction", null, null);
        //personal_introduction:{0},{1},{0}  第二个参数 对应多语的占位符  第三个参数是获取message_en_GB.properties 配置文件
        String messagePersonalIntroductionGb = applicationContext.getMessage ("personal_introduction", new String[]{"test1", "test2"}, new Locale ("en_GB"));
        return message + "-----" + messagePersonalIntroduction + "-----" + messagePersonalIntroductionGb ;
    }
}

配置层

@Configuration
public class ConfigurationMessageSource {
//将名称为messageSource的bean放到容器中
    @Bean
    public MessageSource messageSource() {
        //基于配置文件的方式,获取多语
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource ();
        messageSource.setBasename ("messages");
        //多语的编码
        messageSource.setDefaultEncoding ("UTF-8");
        //每隔多久访问配置文件,当更新配置文件的时候,会动态更新,如果不定义时间,只要更改就会更新多语,影响性能
        messageSource.setCacheMillis(1000);
        return messageSource;
    }
}

配置文件


image.png

message_zh_CN.properties文件,修改配置是会动态更新

name=姓名测试zhCN
personal_introduction=个人介绍:{0},{1},{0}

2.基于数据库的方式

//将名称为messageSource的bean放到容器中
@Component("messageSource")
//类要继承StaticMessageSource ,这个类可以通过编程的方式提供国际化功能
public class MessageSourceFromDb extends StaticMessageSource implements InitializingBean {
    @Autowired
    private TestMapper testMapper;
    @Override
    //使用InitializingBean的方式,是因为这个时候数据源已经初始化好了,保证可以从数据库中获取多语信息
    public void afterPropertiesSet() throws Exception {
//从数据库中获取信息
        List<Test> tests = testMapper.queryAllTests ();
        //此处我们在当前bean初始化之后,模拟从db中获取国际化信息,然后调用addMessage来配置国际化信息
        this.addMessage("desc", Locale.SIMPLIFIED_CHINESE, "我是从db来的信息");
        this.addMessage("desc", Locale.UK, "MessageSource From Db");
    }
}

调用和配置文件方式一致

@Service
public class ServiceTest implements ApplicationContextAware {
    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public String message() {
        //desc的value是数据库获取的
        String desc = applicationContext.getMessage ("desc", null, null);
        return desc;
    }

如何动态更新message

@Autowired
//从容器中获取MessageSourceFromDb
MessageSourceFromDb messageSource;
@Autowired
private TestMapper testMapper;
public void updateMessage() {
    //testMapper.update (); 更新数据库操作 伪代码
    //将数据库的同时更新到内存,这样保证了项目重启初始化阶段会从数据库拿到最新的数据放到内存中
    messageSource.addMessage ("desc", Locale.SIMPLIFIED_CHINESE, "更新后的数据");
}

基于数据库的方式,在动态更新的时候,内存和数据库同时更新,要考虑数据库更新失败的情况,国际化基本都是后台管理,不存在高并发的情况,可以用锁的方式,保持内存和数据库一致.
3.为什么要把名称为messageSource的bean放到容器中

@Override
public String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale) {
//getMessageSource 是从容器中通过名称过去的,bean的名称就是messageSource
   return getMessageSource().getMessage(code, args, defaultMessage, locale);
}

相关文章

网友评论

      本文标题:spring国际化

      本文链接:https://www.haomeiwen.com/subject/evaebrtx.html