log4j对xml配置解析
以下是log4j.xml对appender的定义例子
<appender name=""
class="org.apache.log4j.RollingFileAppender">
<param name="File" value="" />
<param name="MaxFileSize" value="" />
<param name="MaxBackupIndex" value="" />
<layout class="org.apache.log4j.PatternLayout"> //父类AppenderSkeleton定义
<param name="ConversionPattern"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} | %p | [%t] %m %n" />
</layout>
</appender>
问题来了layout元素的配置name=”ConversionPattern”,但是PatternLayout中并没有属性ConversionPattern而是pattern,那么现在解析这个xml时候是如何set到pattern中的呢?
大致上看了看源码,log4j通过DOMConfigurator类进行xml配置解析,方法Appender parseAppender (Element appenderElement)进行appender的解析
protected Appender parseAppender (Element appenderElement)
{
......
//解析layout
// Set appender layout
else if (currentElement.getTagName().equals(LAYOUT_TAG)) {
appender.setLayout(parseLayout(currentElement));
}
......
}
parseLayout(currentElement)构造Layout实例
Layout parseLayout (Element layout_element)
{
....new 相应类型Layout实例
//Layout的PropertySetter
PropertySetter propSetter = new PropertySetter(layout);
....获取param元素:currentElement
setParameter(currentElement, propSetter);
}
最终是调用PropertySetter(API)的setProperty方法。
protected void setParameter(Element elem, PropertySetter propSetter)
{
String name = subst(elem.getAttribute(NAME_ATTR));// ConversionPattern
String value = (elem.getAttribute(VALUE_ATTR));// %d{yyyy-MM-dd HH:mm:ss.SSS} | %p | [%t] %m %n
value = subst(OptionConverter.convertSpecialChars(value));
propSetter.setProperty(name, value);
}
public void setProperty(String name, String value)
{
....
PropertyDescriptor prop = getPropertyDescriptor(name);
....
setProperty(prop, name, value);
....
}
该方法在propSetter的PropertyDescriptor[] props中找到baseName与ConversionPattern一致的元素,props[i]包含了对应的setter与getter方法名,用于反射调用。
PropertyDescriptor是java bean的内容
参考:http://blog.youkuaiyun.com/z69183787/article/details/8443777
log4j的xml配置都是使用这种方式进行实例属性的注入,所以元素
< param name=”File” value=”” />
中的name并不对应类的属性名,而是PropertyDescriptor的baseName