详解Strut2中ActionSupport类的日志处理功能
来源:互联网 发布:php mvp 编辑:程序博客网 时间:2024/04/29 03:12
要点:
1.strut2是依赖于xwork这个包,这一点也struts1与struts2的区别之一。
2.在strut2中ActionSupport类的Logger对象LOG,它是一个静态对象,通过日志工厂LoggerFactory去获取的。在采用STRUTS2进行开发时,可以让action类继承ActionSupport,即可使用Logger进行日志处理(Logger,包含trace debug info warn error fatal等六个层别的打印)
下面通过Logger对象,了解一下Struts2的日志处理过程
ActionSupport持有LOG对象,源码如下:
public class ActionSupport
implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable
{
protected static Logger LOG = LoggerFactory.getLogger(ActionSupport.class);
......
}
那么LoggerFactory方法,getLogger是如何实现的呢?
##########################XWORK包下##########################
首先,LoggerFactory是一个抽象类,它持有一把读写锁lock(ReadWriteLock),以及一个日志工厂factory(LoggerFactory).
private static final ReadWriteLock lock = new ReentrantReadWriteLock();
private static LoggerFactory factory;
提供两个静态方式,获取Logger对象,一种是通过Class<?> cls,一种是通过类名 字符串参数,如Hello.class就用“Hello”,
public static Logger getLogger(Class<?> cls)
{
return getLoggerFactory().getLoggerImpl(cls);
}
public static Logger getLogger(String name) {
return getLoggerFactory().getLoggerImpl(name);
}
从上面看,实现上是调用其自身的实现方法getLoggerImpl,它自身的getLoggerImpl方法如下,都是抽象方法(为什么?往下看方法getLoggerFactory,就知道了)
protected abstract Logger getLoggerImpl(Class<?> paramClass);
protected abstract Logger getLoggerImpl(String paramString);
#################getLoggerFactory();的实现#####################
在理解getLoggerFactory().getLoggerImpl(cls);这个语句之前,我们先理解一下getLoggerFactory();的实现
protected static LoggerFactory getLoggerFactory() {
lock.readLock().lock(); //锁定 读锁
try {
if (factory != null) { //工厂是共用的,如果不用空,返回该工厂对象
LoggerFactory localLoggerFactory = factory;
return localLoggerFactory; //如果不用空,返回该工厂对象
} } finally { lock.readLock().unlock();//解除 读锁
}
lock.writeLock().lock(); //锁定 写锁;前提,如果当前factory为空,需要创建新的工厂,使用ActionSupport 里边的LoggerFactory.getLogger()方法,展开即getLoggerFactory();方法返回值 不为空
try {
if (factory == null) { //important!!!!!! 通过 反射 reflection 获取commons-logging下的LogFactory对象
try {
Class.forName("org.apache.commons.logging.LogFactory");//为什么呢?
factory = new CommonsLoggerFactory();//在写锁当环境中 创建 CommonsLoggerFactory对象,要用到LogFactory对象 ,详细代码,往下看!
}
catch (java.lang.ClassNotFoundException ex) {
factory = new JdkLoggerFactory();
}
}
ex = factory;
return ex; } finally { lock.writeLock().unlock(); } throw localObject2;//解除 写锁
}
注:CommonsLoggerFactory 其实是LoggerFactory的子类,只是它是一个非抽象对象,实现了LoggerFactory的下面的两个实现方法:
protected abstract Logger getLoggerImpl(Class<?> paramClass);
protected abstract Logger getLoggerImpl(String paramString);
################创建 CommonsLoggerFactory 对象 的实现################
public class CommonsLoggerFactory extends LoggerFactory
{
protected Logger getLoggerImpl(Class<?> cls)
{
return new CommonsLogger(LogFactory.getLog(cls));
}
protected Logger getLoggerImpl(String name)
{
return new CommonsLogger(LogFactory.getLog(name));
}
}
#######COMMONS-LOGGIN包下的###
###################### LogFactory对象getLog方法 ,参数为Class cls 的实现################
public static Log getLog(Class clazz)
throws LogConfigurationException
{
return getFactory().getInstance(clazz);
}
在看下commons-logging下的LogFactory类的getFactory()方法的实现之前,
先理解一下LogFactory的静态加载块:
static
{
thisClassLoader = getClassLoader(LogFactory.class); //获取当前类(LogFactory)的类加载器
initDiagnostics();
logClassLoaderEnvironment(LogFactory.class);
factories = createFactoryStore();
if (isDiagnosticsEnabled())
logDiagnostic("BOOTSTRAP COMPLETED");
}
#################initDiagnostics####################
private static void initDiagnostics()
{
try
{
String dest = getSystemProperty("org.apache.commons.logging.diagnostics.dest", null); //读取项目根目录下的commons-loggings.properties文件里边的
//org.apache.commons.logging.diagnostics.dest系统变量
if (dest == null) {
return;
}
}
catch (SecurityException ex)
{
return;
}
String dest;
if (dest.equals("STDOUT"))
diagnosticsStream = System.out;
else if (dest.equals("STDERR"))
diagnosticsStream = System.err;
else {//其他情况、根据文件名创建打印流diagnosticsStream(PrintStream)
try
{
FileOutputStream fos = new FileOutputStream(dest, true);
diagnosticsStream = new PrintStream(fos);
}
catch (IOException ex) {
return;
}
}
String classLoaderName;//初始化classLoaderName类加载器名称
try
{
ClassLoader classLoader = thisClassLoader;
String classLoaderName;
if (thisClassLoader == null)
classLoaderName = "BOOTLOADER";
else
classLoaderName = objectId(classLoader);//objectId返回形式为“该类的完整路径(如java.lang.String)+@+该类在内存中的hashcode编码”
}
catch (SecurityException e)
{
String classLoaderName;
classLoaderName = "UNKNOWN";
}
diagnosticPrefix = "[LogFactory from " + classLoaderName + "] ";//定义诊断前缀字符串
}
#################logClassLoaderEnvironment#######
###################这个类比较简单 ,只是加载类加载器,并打印一些信息####################
##################前提是isDiagnosticsEnabled()为true,即diagnosticsStream(PrintStream) 对象不为空的情况#############
private static void logClassLoaderEnvironment(Class clazz)
{
if (!isDiagnosticsEnabled()) {
return;
}
try
{
logDiagnostic("[ENV] Extension directories (java.ext.dir): " + System.getProperty("java.ext.dir"));
logDiagnostic("[ENV] Application classpath (java.class.path): " + System.getProperty("java.class.path"));
} catch (SecurityException ex) {
logDiagnostic("[ENV] Security setting prevent interrogation of system classpaths.");
}
String className = clazz.getName();
try
{
classLoader = getClassLoader(clazz);
}
catch (SecurityException ex)
{
ClassLoader classLoader;
logDiagnostic("[ENV] Security forbids determining the classloader for " + className);
return;
}
ClassLoader classLoader;
logDiagnostic("[ENV] Class " + className + " was loaded via classloader " + objectId(classLoader));
logHierarchy("[ENV] Ancestry of classloader which loaded " + className + " is ", classLoader);
}
#################createFactoryStore####################
private static final Hashtable createFactoryStore() { //这里返回一个线程安全,支持同步的hashtable对象,用于保存工厂集合
Hashtable result = null;
String storeImplementationClass;
try {
storeImplementationClass = getSystemProperty("org.apache.commons.logging.LogFactory.HashtableImpl", null);//读取系统配置,在commons-loggin.properties下配置
}
catch (SecurityException ex)
{
String storeImplementationClass;
storeImplementationClass = null;
}
if (storeImplementationClass == null)//如果没有配置,读出默认弱hashtable对象
storeImplementationClass = "org.apache.commons.logging.impl.WeakHashtable";
try
{
Class implementationClass = Class.forName(storeImplementationClass);//反射获取该实例返回
result = (Hashtable)implementationClass.newInstance();
}
catch (Throwable t)
{
if (!"org.apache.commons.logging.impl.WeakHashtable".equals(storeImplementationClass))
{
if (isDiagnosticsEnabled())
{
logDiagnostic("[ERROR] LogFactory: Load of custom hashtable failed");
}
else
{
System.err.println("[ERROR] LogFactory: Load of custom hashtable failed");
}
}
}
if (result == null) {
result = new Hashtable();
}
return result;
}
#####################现在静态块代码已经分析完了,只是一个静态加载,比较简单###接下继续前面的Log#################
###############LogFactory类的getFactory()方法的实现##################################
首先调用getContextClassLoaderInternal()方法,通过AccessController对象调用directGetContextClassLoader
#################directGetContextClassLoader 的代码如下##########反射####################################
Method method = Thread.class.getMethod("getContextClassLoader", (Class[])null);
classLoader = (ClassLoader)method.invoke(Thread.currentThread(), (Object[])null);
#########################如果classLoader为空,则返回当前类的加载器########
classLoader = getClassLoader(LogFactory.class);
接下来,通过classLoader类加载器作为参数,获取缓存工厂
factory = getCachedFactory(classLoader)
- 详解Strut2中ActionSupport类的日志处理功能
- Strut2对ActionSupport的封装
- struts2中继承ActionSupport类的作用
- Struts 的 ActionSupport 类
- Struts 2的ActionSupport类的validate()方法详解
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2中actionsupport的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- struts2 中 Actionsupport 的作用
- Strut2中strus.xlm文件的配置详解
- 关于安卓定时服务的小知识
- 认识HTML5的WebSocket
- C#操作Excel文件(读取Excel,写入Excel)
- 值2013来临之际,祝福网友们,新年快乐 合家欢乐!
- Android画图之抗锯齿
- 详解Strut2中ActionSupport类的日志处理功能
- 图像处理公共数据库下载地址集锦
- 温暖别人就是温暖自己
- eclipse插件大全(转自:http://www.iteye.com/topic/738998)
- cyberneko和dom4j解析html
- RLE行程长度压缩算法
- java应用tomcat中实现https安全连接的方法
- C#面试题与答案
- 第9天—15天学习总结