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

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

主题:

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

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

java.util.ResourceBundle
java.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(pig, array);
System.out.println(value);  //最终结果是:ABCDEFGHIJKLMNOPQ

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

myResources.properties:

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

例:

public class ResourceBundleTest {public static void 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);//结果:com.mysql.jdbc.Drvierjdbc:mysql://localhost:3306:testroottest
    }
}

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用于读取properties文件private ResourceBundle bundle;private static org.apache.juli.logging.Log log=org.apache.juli.logging.LogFactory.getLog( StringManager.class );// 私有的构造方法能够保证外界无法实例化自己,这也是单例实现的关键步骤private 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 还是要保证不是nullif (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// objects and barf outtry {// 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;}// 下面四个getString方法,最终都需要调用getString(String key, Object[] args)public 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维护整个tomcat的StringManagerprivate static Hashtable managers = new Hashtable();// 保证一个包一个StringManager,私有化构造函数+Hashtable维护实现(值得学习)// 从而避免大量的StringManager实例化和销毁的操作,毕竟写日志属于比较频繁的操作。public synchronized static StringManager getManager(String packageName) {// 用一个Hashtable来管理控制,保证每个包提供一个StringManagerStringManager mgr = (StringManager)managers.get(packageName);// 属于这个包的Manager有了吗if (mgr == null) {mgr = new StringManager(packageName);// 实例化好后,把它放进Hashtable里去,下次就不用实例化了
            managers.put(packageName, mgr);}return mgr;}
}

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

让我们继续前行

----------------------------------------------------------------------

努力不一定成功,但不努力肯定不会成功。
共勉

转载于:https://www.cnblogs.com/killbug/archive/2012/10/17/2728551.html

Tomcat StringManager阅读学习 -我们到底能走多远系列(10)相关推荐

  1. html5实现饼图和线图-我们到底能走多远系列(34)

    我们到底能走多远系列(34) 扯淡: 送给各位一段话:     人生是一个不断做加法的过程 从赤条条无牵无挂的来 到学会荣辱羞耻 礼仪规范 再到赚取世间的名声 财富 地位 但是人生还要学会做减法 财富 ...

  2. Java 阶段面试 知识点合集 - 我们到底能走多远系列(15)

    我们到底能走多远系列(15) 扯淡:这些知识点来源是通过面试涉及到的,面的公司不多,知识点涉及也不多,我每次面试后都在备忘录里写下有用的东西,集合起来分享一下,因为是知识点,所以就不出什么面试题目啦. ...

  3. js中this和回调方法循环-我们到底能走多远系列(35)

    我们到底能走多远系列(35) 扯淡: 13年最后一个月了,你们在13年初的计划实现了吗?还来得及吗? 请加油~ 主题: 最近一直在写js,遇到了几个问题,可能初入门的时候都会遇到吧,总结下. 例子: ...

  4. 图片尺寸判断等-我们到底能走多远系列(21)

    我们到底能走多远系列(21) 扯淡:又是一年过年,给各位拜个很早很早的年,实在点的祝福:祝各位明年工资全部翻一番啦! 主题: 1,判断上传图片尺寸功能 如下代码即可在页面上结果掉这个问题: var i ...

  5. 程序员在写作这条路上到底能走多远?

    01 杨过这辈子什么时候最痛苦?被郭襄她姐砍掉了一只胳膊的时候,那时他身中情花之毒,活不了多久了,他最爱的姑姑又不辞而别:在这个时候,他想到的就是一个人偷偷地离开,做好了告别这个世界的准备. 我在什么 ...

  6. 网红经济到底能走多远?

    网红经济是以一位年轻貌美的时尚达人为形象代表,以红人的品味和眼光为主导,进行选款和视觉推广,在社交媒体上聚集人气,依托庞大的粉丝群体进行定向营销,从而将粉丝转化为购买力的一个过程.n由于变现能力强大, ...

  7. 计算机在3d打印发挥的作用,七大优势汇总 看3D打印的路到底能走多远

    [PConline 资讯]3D打印到底是什么?其实很多人都会认为它只不过是一种将二维喷墨或激光打印立体化的产品,很多人对于这多出的一个维度到底意味着什么概念比较模糊.先进的生产力一向都是经济发展不可或 ...

  8. Paddle Graph Learning (PGL)图学习之图游走类deepwalk、node2vec模型[系列四]

    Paddle Graph Learning (PGL)图学习之图游走类模型[系列四] 更多详情参考:Paddle Graph Learning 图学习之图游走类模型[系列四] https://aist ...

  9. 争议中的分销式社交电商能走多远?

    争议中的分销式社交电商能走多远? 最近和几个做社群经济的大咖朋友聊天,都谈到今年火遍朋友圈的社交电商.社交电商到底有多火?据中商产业研究院<2018中国社交电商行业发展报告>显示,2018 ...

  10. Java源码阅读学习后的浅析和感悟(JDK篇)(持续更新)

    目录 Java源码阅读学习后的浅析和感悟(JKD篇) - 为什么阅读源码 集合框架类 - 为什么会要引入集合 - 集合结构图(部分) ArrayList集合源码分析 - 扩容机制 - 关键方法解释(D ...

最新文章

  1. php 时间转换编号,PHP 时间的格式转换
  2. python+unittest+excel接口自动化_Python+requests+unittest+excel实现接口自动化测试框架
  3. 确认过眼神(*╹▽╹*),这就是大家想要的BCH
  4. aapt2 生成资源 public flag 标记
  5. XML文件与实体类的互相转换
  6. 省队集训Day3 tree
  7. 如何防止机器模拟请求
  8. 编写自己的Matcher与如何让编译器识别被mock的重载函数
  9. JVM详解之:类的加载链接和初始化
  10. 【Git】Git-常用命令备忘录(二)
  11. Hive的数据加载与导出
  12. hashmap put复杂度_你碰到过几种HashMap在高并发下出现的问题,哪些可能出现的问题...
  13. python中qt有哪些控件_使用PyQt5调用Qt程序,基础PythonQt控件的使用方法
  14. 搜狗输入法 linux 源码,1.下载搜狗输入法for linux源码包:
  15. teamtalk部署启动顺序
  16. 抖音搬运视频如何伪原创
  17. 《XX项目产品需求说明书-精华版》
  18. 机器人算法工程师入门指南(四)常用技能与如何备战offer
  19. 【观察】从VCF云能力九宫格,看懂“真”全栈企业云平台
  20. 用combobox计算价钱_冷水机组价钱_宏晟博源

热门文章

  1. 网卡是如何将包转换成电信号并发送到网线中的
  2. 使用redis kv数据库维护kafka主题分区的offset
  3. 在zephyr上使用mipi-sys-t
  4. 《深入应用C++11:代码优化与工程级应用》勘误表
  5. jQuery获取元素坐标
  6. 构建一个可靠的分布式计数器--memcached之incr/decr操作实战分析
  7. Object.create()和深拷贝
  8. 316 Remove Duplicate Letters 去除重复字母
  9. HTTP权威协议笔记-6.代理
  10. ubuntu命令整理中