Spring消息代码理解

一、简介

1、Spring消息体系的定义:

①消息取得接口:MessageSource、HierarchicalMessageSource
②消息参数接口:MessageSourceResolvable

2、Spring消息体系的实现:

①消息取得:AbstractMessageSource、ResourceBundleMessageSource、ReloadableResourceBundleMessageSource、StaticMessageSource
②消息参数:DefaultMessageSourceResolvable、FieldError、ObjectError

3、Spring消息体系的使用:

①ApplicationContext、MessageSourceAware

二、Spring消息体系的定义
1、MessageSource:

定义个三个getMessage操作:

•String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
•String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
•String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
Spring为一个取得消息的操作,提供了三个方法,细化了取消息操作的不同需求。一种提供默认消息,不报异常;一种不提供默认消息,报NoSuchMessageException;一种使用MessageSourceResolvable封装需要的参数,虽然封装的参数中提供了默认消息,但为防止提供了无效的默认消息,还是报了NoSuchMessageException。

2、HierarchicalMessageSource:

继承MessageSource接口,添加了两个操作:

•void setParentMessageSource(MessageSource parent);
•MessageSource getParentMessageSource();
Spring通过这两个方法提供了一种实现MessageSource层次的定义

3、MessageSourceResolvable:

为了方便MessageSource的使用,Spring定义了取消息使用的参数对象,提供了三个操作:

•public String[] getCodes();
•public Object[] getArguments();
•public String getDefaultMessage();
4、接口定义中的智慧

①MessageSource与HierarchicalMessageSource接口的分离,为两个不同的目的都定义了清晰的接口。虽然了Spring的MessageSource的实现都继承与HierarchicalMessageSource,当时因为MessageSource接口的存在,可以使ApplicationContext接口直接提供一个标准的取得消息的方法集,而不用去关心消息体系的具体实现。
②提供MessageSourceResolvable接口,方便消息的使用。取得消息时不需要自己组织多个参数,而是直接将一个MessageSourceResolvable的实现传入即可。
③MessageSourceResolvable接口为什么不提供getLocal()操作?国际化应该是与业务实现无关,不应该是由业务实现去考虑。最好通过配置,或其他方法自动取得。

三、Spring消息体系的实现
1、AbstractMessageSource

①实现了HierarchicalMessageSource接口,提供了MessageSource的一个基本的抽象实现,并提供protected abstract MessageFormat resolveCode(String code, Locale locale);方法,留给子类自己决定自己的国际化实现。
②提供的属性:

•private boolean useCodeAsDefaultMessage = false;
定义当没有提供Default Message时,是否使用Message Code作为Default Message。

•private boolean alwaysUseMessageFormat = false;
当没有消息参数时,是否还是使用MessageFormat。当消息中包含一些需要MessageFormat特殊处理的逃逸字符时,需要设置为true。
③实现操作祥解:

•void setParentMessageSource(MessageSource parent);
•MessageSource getParentMessageSource();
④实现了消息的层次操作,并将父MessageSource保存。

•String getMessage(String code, Object[] args, String defaultMessage, Locale locale);
•String getMessage(String code, Object[] args, Locale locale) throws NoSuchMessageException;
•String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
所有取得消息的操作都有getMessageInternal()方法实现。根据默认消息取得默认消息时,使用renderDefaultMessage()方法。无默认消息根据useCodeAsDefaultMessage属性,取得默认消息时使用getDefaultMessage()方法。
⑤getMessageInternal()方法的实现:

•无消息参数,且alwaysUseMessageFormat为false时,调用resolveCodeWithoutArguments()方法直接取得消息。其实在resolveCodeWithoutArguments()方法的实现中还是使用MessageFormat,所以Spring建议在子类中覆盖resolveCodeWithoutArguments()方法。
•否则,先调用resolveArguments()方法将参数中的MessageSourceResolvable实例转化为对应的消息,然后调用resolveCode()取得MessageFormat,之后使用MessageFormat处理消息。
•当没有找到消息时,调用getMessageFromParent()方法,从父MessageSource中查找消息。
⑥cachedMessageFormats
考虑到多数DefaultMessage都是一些同样错误消息,所以Spring使用一个HashMap—cachedMessageFormats缓存了DefaultMessage的MessageFormat。

2、StaticMessageSource
继承AbstractMessageSource类,提供了最简单的MessageSource的实现。提供了两个操作:

•addMessage()将消息编号和对应的MessageFormat保存于一个HashMap中。
•resolveCode()根据消息编号和Local从HashMap中取得对应的MessageFormat。
3、ResourceBundleMessageSource
继承AbstractMessageSource类,实现了BeanClassLoaderAware接口,提供了一种使用Resource Bundle的Message Source的实现。

•basenames属性
可以指定一个或一组查找message的文件,可包含目录和Classpath。
resolveCodeWithoutArguments()覆盖了父类的对应方法,实现了直接从配置文件读取message并直接返回,不使用MessageFormat。

•resolveCode()
调用getResourceBundle()取得对应的ResourceBundle,然后通过取得的ResourceBundle取得对应的MessageFormat。

•ResourceBundleMessageSource中的缓存实现。
•ResourceBundle缓存
针对每一个Basename都缓存一个不同Local的HashMap。

•MessageFormat缓存
针对每一个ResourceBundle都缓存一个Code的Map,其中缓存了一个Code的不同Local的MessageFormat。

4、ReloadableResourceBundleMessageSource

继承AbstractMessageSource类,实现了ResourceLoaderAware接口,提供了一种可以Reload的MessageSource的实现。
通过自己实现的PropertiesPersister和PropertiesHolder,跳过ResoureBundle的缓存机制,实现一个可以刷新的MessageSoruce。

四、Spring消息体系的使用

1.ApplicationContext
实现了MessageSource接口,将getMessage的调用转发给实际的MessageSource的实现。
2.MessageSourceAware
当Spring的IOC容器发现实现了此接口的实例,就会将ApplicationContext注入到此实例中。

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/shrekmu/archive/2007/05/20/1617795.aspx

你可能感兴趣的:(spring,.net,Blog,IOC)