Spring(21)——国际化MessageSource

本文详细介绍了Spring框架中的MessageSource接口及其主要实现类ResourceBundleMessageSource和ReloadableResourceBundleMessageSource,用于支持国际化和参数替换。ResourceBundleMessageSource基于JDK的ResourceBundle,提供缓存功能,而ReloadableResourceBundleMessageSource允许指定非类路径下的资源文件,支持文件类型更广泛。文章通过示例展示了如何配置和使用这两个实现类,并讨论了缓存、编码、回退机制等相关特性。

21 国际化MessageSource

Spring中定义了一个MessageSource接口,以用于支持信息的国际化和包含参数的信息的替换。MessageSource接口的定义如下,对应的方法说明已经在方法上注释了。

public interface MessageSource {

	/**
	 * 解析code对应的信息进行返回,如果对应的code不能被解析则返回默认信息defaultMessage。
	 * @param 需要进行解析的code,对应资源文件中的一个属性名
	 * @param 需要用来替换code对应的信息中包含参数的内容,如:{0},{1,date},{2,time}
	 * @param defaultMessage 当对应code对应的信息不存在时需要返回的默认值
	 * @param locale 对应的Locale
	 * @return
	 */
	String getMessage(String code, Object[] args, String defaultMessage, Locale locale);

	/**
	 * 解析code对应的信息进行返回,如果对应的code不能被解析则抛出异常NoSuchMessageException
	 * @param code 需要进行解析的code,对应资源文件中的一个属性名
	 * @param args 需要用来替换code对应的信息中包含参数的内容,如:{0},{1,date},{2,time}
	 * @param locale 对应的Locale
	 * @return 
	 * @throws NoSuchMessageException 如果对应的code不能被解析则抛出该异常
	 */
	String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;

	/**
	 * 通过传递的MessageSourceResolvable对应来解析对应的信息
	 * @param resolvable 
	 * @param locale 对应的Locale
	 * @return 
	 * @throws NoSuchMessageException 如不能解析则抛出该异常
	 */
	String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;

}

我们熟悉的ApplicationContext接口继承了MessageSource接口,所以我们所有的ApplicationContext实现类都实现了MessageSource接口,也就是我们我们可以通过ApplicationContext来调用MessageSource接口方法以实现信息的国际化和替换信息中包含的参数。所有ApplicationContext实现类对MessageSource接口的实现都是在AbstractApplicationContext中实现的,其对MessageSource接口实现的源码如下:

@Override
public String getMessage(String code, Object args[], String defaultMessage, Locale locale) {
	return getMessageSource().getMessage(code, args, defaultMessage, locale);
}

@Override
public String getMessage(String code, Object args[], Locale locale) throws NoSuchMessageException {
	return getMessageSource().getMessage(code, args, locale);
}

@Override
public String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException {
	return getMessageSource().getMessage(resolvable, locale);
}

/**
 * Return the internal MessageSource used by the context.
 * @return the internal MessageSource (never {@code null})
 * @throws IllegalStateException if the context has not been initialized yet
 */
private MessageSource getMessageSource() throws IllegalStateException {
	if (this.messageSource == null) {
		throw new IllegalStateException("MessageSource not initialized - " +
				"call 'refresh' before accessing messages via the context: " + this);
	}
	return this.messageSource;
}

从中我们可以看到AbstractApplicationContext对MessageSource的实现都是自身所持有的MessageSource类型的messageSource对象来实现的。那么对应的messageSource又是如何初始化的呢?在其中定义了一个initMessageSource()来做对应的初始化工作,其源码如下。

/**
 * Initialize the MessageSource.
 * Use parent's if none defined in this context.
 */
protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = b
### Spring - context 概述 Spring - context 是 Spring 框架的核心模块之一,它提供了依赖注入(DI)和控制反转(IoC)容器的支持,以及其他企业级服务,如事件传播、资源加载、国际化等。 ### 功能介绍 - **依赖注入和 IoC 容器**:Spring - context 实现了强大的 IoC 容器,它负责创建和管理对象(Bean),并通过依赖注入的方式将对象之间的依赖关系进行解耦。例如,可以通过 XML 配置、Java 注解或 Java 配置类来定义 Bean 及其依赖关系。 ```xml <!-- XML 配置示例 --> <bean id="userService" class="com.example.UserService"> <property name="userRepository" ref="userRepository"/> </bean> <bean id="userRepository" class="com.example.UserRepository"/> ``` ```java // Java 注解示例 import org.springframework.stereotype.Service; import org.springframework.beans.factory.annotation.Autowired; @Service public class UserService { private UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } } ``` - **事件机制**:Spring - context 提供了事件传播机制,允许应用程序中的组件发布和监听事件。这有助于实现松耦合的组件通信。例如,当用户注册成功后,可以发布一个用户注册事件,其他组件可以监听该事件并执行相应的操作。 ```java import org.springframework.context.ApplicationEvent; // 自定义事件类 public class UserRegisteredEvent extends ApplicationEvent { public UserRegisteredEvent(Object source) { super(source); } } import org.springframework.context.ApplicationListener; import org.springframework.stereotype.Component; // 事件监听器 @Component public class UserRegisteredListener implements ApplicationListener<UserRegisteredEvent> { @Override public void onApplicationEvent(UserRegisteredEvent event) { // 处理用户注册事件 } } ``` - **资源加载**:Spring - context 提供了统一的资源加载接口 `ResourceLoader`,可以方便地加载各种类型的资源,如文件、类路径资源、URL 资源等。 ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.Resource; public class ResourceLoadingExample { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); Resource resource = context.getResource("classpath:config.properties"); // 处理资源 } } ``` - **国际化支持**:Spring - context 支持国际化(i18n),可以根据用户的语言环境提供不同的文本信息。通过配置消息源和使用 `MessageSource` 接口,可以轻松实现国际化功能。 ```xml <!-- 配置消息源 --> <bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"> <property name="basename" value="messages"/> </bean> ``` ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class InternationalizationExample { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); String message = context.getMessage("welcome.message", null, java.util.Locale.ENGLISH); System.out.println(message); } } ``` ### 使用指南 1. **添加依赖**:如果使用 Maven 项目,在 `pom.xml` 中添加 Spring - context 依赖。 ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.23</version> </dependency> ``` 2. **配置 Bean**:可以使用 XML 配置、Java 注解或 Java 配置类来定义和配置 Bean。 3. **启动 Spring 容器**:根据配置方式的不同,使用相应的方式启动 Spring 容器。 ```java import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { // 启动 XML 配置的 Spring 容器 ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); // 获取 Bean UserService userService = context.getBean(UserService.class); // 使用 Bean userService.doSomething(); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值