另外,在Log4J中,ObjectRenderer之间也是遵循类型继承关系的。假如现在有一个新的对象叫User,并且Student继承User类:
public class User {
private Long id;
private String name;
public User(Long id, String name) {
this.id = id;
this.name = name;
}
}
public class Student extends User {
private Integer age;
public Student(Long id, String name, Integer age) {
super(id, name);
this.age = age;
}
}
如果这个时候,我们再创建一个UserRenderer:
package cd.itcast.log4j;
import org.apache.log4j.or.ObjectRenderer;
public class UserRender implements ObjectRenderer {
@Override
public String doRender(Object o) {
if (o instanceof User) {
User u=(User)o;
return "USER: [id: "+u.getId()+",name: "+u.getName();
}
return o.toString();
}
}
如果这个时候,如果我们只注册了UserRender:
@Test
public void testObjectRender2() {
BasicConfigurator.configure();
RendererMap.addRenderer((RendererSupport) Logger.getRootLogger().getLoggerRepository(),
User.class.getName(), UserRender.class.getName());
Student s = new Student(1l, "itcast", 16);
Logger log = Logger.getLogger("cd.itcast");
log.debug(s);
}
那么Log4J在输出Student的时候,也会使用UserRender来合成,如果这个时候,UserRender和StudentRender同时注册:
@Test
public void testObjectRender2() {
BasicConfigurator.configure();
RendererMap.addRenderer((RendererSupport) Logger
.getRootLogger().getLoggerRepository(),
User.class.getName(), UserRender.class.getName());
RendererMap.addRenderer((RendererSupport) Logger
.getRootLogger().getLoggerRepository(),
Student.class.getName(), StudentRender.class.getName());
Student s = new Student(1l, "itcast", 16);
Logger log = Logger.getLogger("cd.itcast");
log.debug(s);
}
则Log4j又会选择StudentRender来合成。这里面的规则是很明显的。
另外,如果使用代码配置,非常麻烦,在使用properties配置的时候,又该怎么注册ObjectRenderer?
@Test
public void testObjectRenderReg() {
PropertyConfigurator.configure(this.getClass()
.getClassLoader().getResourceAsStream("log4j.properties"));
Student s = new Student(1l, "itcast", 16);
Logger log = Logger.getLogger("cd.itcast");
log.debug(s);
}
首先还是把配置切换成PropertyConfigurator,在log4j.properties文件里面:
log4j.rootLogger=DEBUG,A
log4j.appender.A=org.apache.log4j.ConsoleAppender
log4j.appender.A.layout=org.apache.log4j.SimpleLayout
log4j.renderer.cd.itcast.log4j.Student=cd.itcast.log4j.StudentRender
前3条配置前面已经讲的很清楚了,关键第4条配置,使用的格式为:
log4j.renderer.renderTargetClassFullQualifiedName=rendererClassFullQualifiedName
在这里,即使用cd.itcast.log4j.StudentRender来render类型为cd.itcast.log4j.Student的类。运行测试,输出:
DEBUG - student: [id: 1,name: itcast,age: 16]
符合我们的预期。同样,在XML中配置ObjectRenderer也是非常简单的,我们把上面的log4j.properties翻译成对应的XML配置就是:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
<renderer renderedClass="cd.itcast.log4j.Student" renderingClass="cd.itcast.log4j.StudentRender"/>
<appender name="A" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout" />
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="A"/>
</root>
</log4j:configuration>
注意加粗的配置。在XML中,使用renderer元素来注册ObjectRenderer。在该元素中有两个属性,renderedClass,即需要被render的目标对象的全限定名;而renderingClass则是自定义的ObjectRenderer的实现类的全限定名。
【成都传智播客java培训★http://url.cn/NdQlYr】