最近参与了一个境外钱包的项目,要求是实现SpringMVC的动态国际化功能,以应对多国家多语言快速切换配置。
之前用Spring做国际化,都将国际化信息写在properties文件中。这次在项目中遇到一个需求,需要把properties文件去掉,直接从数据库读取国际化信息。
在网上查了好多资料,和很多朋友一样一直卡在一个地方一直出不来,就是Spring容器初始化时,要查询数据库国际化表里的国际化数据时,DAO层接口一直注入不进来,导致查库动作不能正常执行。翻了好多博客,都是错误的,最后终于搞清楚问题出在了哪里!
一开始我看一些博客的代码,按照他们的方式做时,数据库查询的依赖一直注入不进来,他们的写法是将初始化的查询方法写在了MessageSource的无参构造器中,目的是希望服务器初始化MessageSource类是,顺便加载查询方法,以便把所有的国际化数据加载到缓存中,可是实际上容器在初始化,Spring容器还没有加载完就去调用Dao层查询服务,于是找不到要加载的bean,所以Spring注入依赖失败,查不到国际化数据。
那么接下来,我们要解决的问题就是在Spring容器初始化时,在所有bean被注入到容器中之后,我们再去注入Dao层的查询方法,我用的方法是实现Spring的一个接口InitializingBean,实现方法afterPropertiesSet()方法,可以在Bean被加载完成后,执行你要执行的方法,OK大致解决方案就这样了,下面来看下代码吧:
大部分的配置都是原汁原味的,重点可以到MessageSource类中去寻找
SpringMVC配置文件
<!-- 定义国际化文件和编码 -->
<bean id="propertiesMessageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basenames" value="messages/message"/>
<property name="defaultEncoding" value="utf8" />
</bean>
<!-- 使用session判断用户语言 -->
<bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver">
<property name="defaultLocale" value="cn"/>
</bean>
<mvc:interceptors>
<bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
<property name="paramName" value="locale"/>
</bean>
</mvc:interceptors>
<!-- 数据库国际化资源 自定义的MessageResource -->
<bean id="messageSource" class="com.platform.i18n.MessageResource">
<property