Tomcat StringManager阅读学习

我们到底能走多远系列(10)

扯淡:空闲时间不多,扯淡时间久更少了。

主题:

 先了解下两个所谓的知识点:ResourceBundle 和MessageFormat

在项目里用的得心应手的properites文件,大多要用到这两个类吧。

java.util.ResourceBundlejava.text.MessageFormat

1,ResourceBundle解析资源文件分两步:1加载资源文件,2获取资源文件中的信息

// 加载资源文件ResourceBundle resource = ResourceBundle.getBundle(“messages”);// 获取资源文件中的信息String driverName = resource.getString(“database.driver”);

ResourceBundle支持多国语言:先把文件名取成类似这样myres_zh_CN.properties

然后:

Locale locale1 = new Locale(“zh”, “CN”);ResourceBundle resb1 = ResourceBundle.getBundle(“myres”, locale1);resb1.getString(“aaa”);

2,MessageFormat用来格式化一个消息(字符串嘛)

直接网上类似代码:

String pig = “{0}{1}{2}{3}{4}{5}{6}{7}{8}{9}{10}{11}{12}{13}{14}{15}{16}”; Object[] array = new Object[]{“A”,”B”,”C”,”D”,”E”,”F”,”G”,”H”,”I”,”J”,”K”,”L”,”M”,”N”,”O”,”P”,”Q”}; String value = MessageFormat.format(message, array); System.out.println(value); //最终结果是:ABCDEFGHIJKLMNOPQ

3,结合在一起就可以实现,将properites文件解析出想要的消息体,然后格式化后给上一层方法用。

myResources.properties:

database.driver=com.mysql.jdbc.Drvierdatabase.url=jdbc:mysql://localhost:3306:testdatabase.user={0}database.pass={0}

例:

public class ResourceBundleTest { main(String[] args) {// 指明包路径和文件名即可ResourceBundle resource = ResourceBundle.getBundle(“code.stu.ResourceBundle.myResources”);String driverName = resource.getString(“database.driver”);String url = resource.getString(“database.url”);Object[] array1 = new Object[]{“root”};Object[] array2 = new Object[]{“test”};// 取得字符串,直接格式化String user = MessageFormat.format(resource.getString(“database.user”), new Object[]{“root”});String pass = MessageFormat.format(resource.getString(“database.pass”), new Object[]{“test”});System.out.println(driverName + url + user + pass); }}

StringManager

在tomcat里,把错误日志信息的字符串写在properites文件里,如此一来,打印日志的事情就可以通过上面的两个类来解决了。

StringManager是管理打印日志的类,Tomcat的设计是,对每一个包提供自己的properites文件,也就是说,每一个包的日志信息只需要去各自包的properites文件里去找就可以了,然后Tomcat为每一个包提供一个StringManager实例,相当于一个包一个单例的效果(值得学习下)。各自的StringManager实例来管理各自包下的日志打印。

源码如下:

package org.apache.catalina.util;import java.text.MessageFormat;import java.util.Hashtable;import java.util.Locale;import java.util.MissingResourceException;import java.util.ResourceBundle;import java.net.URLClassLoader;public class StringManager { ResourceBundle bundle;private static org.apache.juli.logging.Log log=org.apache.juli.logging.LogFactory.getLog( StringManager.class ); StringManager(String packageName) {// properties文件所在的package+“.LocalStrings”// 所有tomcat的日志使用的properties文件都依照这个形式来命名的String bundleName = packageName + “.LocalStrings”;try {// 根据bundleName取得解析资源文件的实例bundle = ResourceBundle.getBundle(bundleName);return;} catch( MissingResourceException ex ) {// 好吧,异常就先不管了。// Try from the current loader ( that’s the case for trusted apps )ClassLoader cl=Thread.currentThread().getContextClassLoader();if( cl != null ) {try {bundle=ResourceBundle.getBundle(bundleName, Locale.getDefault(), cl);return;} catch(MissingResourceException ex2) {}}if( cl==null )cl=this.getClass().getClassLoader();if (log.isDebugEnabled())log.debug(“Can’t find resource ” + bundleName +” ” + cl);if( cl instanceof URLClassLoader ) {if (log.isDebugEnabled())log.debug( ((URLClassLoader)cl).getURLs());}}}/*** Get a string from the underlying resource bundle.** @param key The resource name*/public String getString(String key) {return MessageFormat.format(getStringInternal(key), (Object [])null);}protected String getStringInternal(String key) {(key == null) {String msg = “key is null”;throw new NullPointerException(msg);}// 返回stringString str = null;if( bundle==null )return key;try {// 资源文件里去查有没有对应的内容str = bundle.getString(key);} catch (MissingResourceException mre) {str = “Cannot find message associated with key ‘” + key + “‘”;}return str;}public String getString(String key, Object[] args) {String iString = null;String value = getStringInternal(key);// this check for the runtime exception is some pre 1.1.6// VM’s don’t do an automatic toString() on the passed in {// ensure the arguments are not null so pre 1.2 VM’s don’t barfObject nonNullArgs[] = args;for (int i=0; i<args.length; i++) {if (args[i] == null) {if (nonNullArgs==args) nonNullArgs=(Object[])args.clone();nonNullArgs[i] = “null”;}}// 格式化,就是把一些变化的参数插入到value这个string中去,格式化成一个新的最终的stringiString = MessageFormat.format(value, nonNullArgs);} catch (IllegalArgumentException iae) {StringBuffer buf = new StringBuffer();buf.append(value);for (int i = 0; i < args.length; i++) {buf.append(” arg[” + i + “]=” + args[i]);}iString = buf.toString();}return iString;} String getString(String key, Object arg) {Object[] args = new Object[] {arg};return getString(key, args);}public String getString(String key, Object arg1, Object arg2) {Object[] args = new Object[] {arg1, arg2};return getString(key, args);}public String getString(String key, Object arg1, Object arg2,Object arg3) {Object[] args = new Object[] {arg1, arg2, arg3};return getString(key, args);}public String getString(String key, Object arg1, Object arg2,Object arg3, Object arg4) {Object[] args = new Object[] {arg1, arg2, arg3, arg4};return getString(key, args);}Hashtable managers = new Hashtable();// 保证一个包一个StringManager,香港虚拟主机,私有化构造函数+Hashtable维护实现(值得学习) StringManager getManager(String packageName) {// 用一个Hashtable来管理控制,保证每个包提供一个StringManagerStringManager mgr = (StringManager)managers.get(packageName);(mgr == null) {mgr = new StringManager(packageName);// 实例化好后,把它放进Hashtable里去,下次就不用实例化了managers.put(packageName, mgr);}return mgr;}}

总结:记得以前连单例是神马都不知道,现如今可以按包给单例,我想还会有更多变化可以学习。没有做不到,只有想不到,美国空间,哈哈。

让我们继续前行

———————————————————————-

努力不一定成功,网站空间,但不努力肯定不会成功。共勉

一个人最大的破产是绝望,最大的资产是希望。

Tomcat StringManager阅读学习

相关文章:

你感兴趣的文章:

标签云: