在上一篇文章中
总结了装饰器模式,现在将装饰器结合实际应用起来。
使用装饰器模式改造slf4j
打印json
格式日志,以便于日志的分析
一、准备
装饰器模式得有一个抽象组件Component
这里的抽象组件可以直接是org.slf4j.Logger
,org.slf4j.LoggerFactory#getLogger(java.lang.Class)
可以看作是一个具体组件(Concrete Component)
。
还缺少装饰器(Decorator)
和具体组件
(Concrete
Decorator
)
二、实现
2.1 装饰器JsonLoggerDecorator
publicclassJsonLoggerDecoratorimplementsLogger { protectedfinalLoggerlogger; publicJsonLoggerDecorator(Loggerlogger) { this.logger=logger; } publicStringgetName() { returnnull; } publicbooleanisTraceEnabled() { returnfalse; } publicvoidtrace(Stringmsg) { } publicvoidtrace(Stringformat, Objectarg) { } publicvoidtrace(Stringformat, Objectarg1, Objectarg2) { } publicvoidtrace(Stringformat, Object... arguments) { } publicvoidtrace(Stringmsg, Throwablet) { } publicbooleanisTraceEnabled(Markermarker) { returnfalse; } publicvoidtrace(Markermarker, Stringmsg) { } publicvoidtrace(Markermarker, Stringformat, Objectarg) { } publicvoidtrace(Markermarker, Stringformat, Objectarg1, Objectarg2) { } publicvoidtrace(Markermarker, Stringformat, Object... argArray) { } publicvoidtrace(Markermarker, Stringmsg, Throwablet) { } publicbooleanisDebugEnabled() { returnfalse; } publicvoiddebug(Stringmsg) { } publicvoiddebug(Stringformat, Objectarg) { } publicvoiddebug(Stringformat, Objectarg1, Objectarg2) { } publicvoiddebug(Stringformat, Object... arguments) { } publicvoiddebug(Stringmsg, Throwablet) { } publicbooleanisDebugEnabled(Markermarker) { returnfalse; } publicvoiddebug(Markermarker, Stringmsg) { } publicvoiddebug(Markermarker, Stringformat, Objectarg) { } publicvoiddebug(Markermarker, Stringformat, Objectarg1, Objectarg2) { } publicvoiddebug(Markermarker, Stringformat, Object... arguments) { } publicvoiddebug(Markermarker, Stringmsg, Throwablet) { } publicbooleanisInfoEnabled() { returnfalse; } publicvoidinfo(Stringmsg) { } publicvoidinfo(Stringformat, Objectarg) { } publicvoidinfo(Stringformat, Objectarg1, Objectarg2) { } publicvoidinfo(Stringformat, Object... arguments) { } publicvoidinfo(Stringmsg, Throwablet) { } publicbooleanisInfoEnabled(Markermarker) { returnfalse; } publicvoidinfo(Markermarker, Stringmsg) { } publicvoidinfo(Markermarker, Stringformat, Objectarg) { } publicvoidinfo(Markermarker, Stringformat, Objectarg1, Objectarg2) { } publicvoidinfo(Markermarker, Stringformat, Object... arguments) { } publicvoidinfo(Markermarker, Stringmsg, Throwablet) { } publicbooleanisWarnEnabled() { returnfalse; } publicvoidwarn(Stringmsg) { } publicvoidwarn(Stringformat, Objectarg) { } publicvoidwarn(Stringformat, Object... arguments) { } publicvoidwarn(Stringformat, Objectarg1, Objectarg2) { } publicvoidwarn(Stringmsg, Throwablet) { } publicbooleanisWarnEnabled(Markermarker) { returnfalse; } publicvoidwarn(Markermarker, Stringmsg) { } publicvoidwarn(Markermarker, Stringformat, Objectarg) { } publicvoidwarn(Markermarker, Stringformat, Objectarg1, Objectarg2) { } publicvoidwarn(Markermarker, Stringformat, Object... arguments) { } publicvoidwarn(Markermarker, Stringmsg, Throwablet) { } publicbooleanisErrorEnabled() { returnfalse; } publicvoiderror(Stringmsg) { } publicvoiderror(Stringformat, Objectarg) { } publicvoiderror(Stringformat, Objectarg1, Objectarg2) { } publicvoiderror(Stringformat, Object... arguments) { } publicvoiderror(Stringmsg, Throwablet) { } publicbooleanisErrorEnabled(Markermarker) { returnfalse; } publicvoiderror(Markermarker, Stringmsg) { } publicvoiderror(Markermarker, Stringformat, Objectarg) { } publicvoiderror(Markermarker, Stringformat, Objectarg1, Objectarg2) { } publicvoiderror(Markermarker, Stringformat, Object... arguments) { } publicvoiderror(Markermarker, Stringmsg, Throwablet) { } }
2.2 具体装饰器JsonLogger
importcom.alibaba.fastjson.JSONObject; importorg.slf4j.Logger; importjava.util.Arrays; publicclassJsonLoggerextendsJsonLoggerDecorator { publicJsonLogger(Loggerlogger) { super(logger); } publicvoidinfo(Stringmsg) { JSONObjectjsonObject=this.newJsonObject(); jsonObject.put("message", msg); logger.info(jsonObject.toJSONString()); } publicvoiderror(Stringmsg) { JSONObjectjsonObject=this.newJsonObject(); jsonObject.put("message", msg); logger.error(jsonObject.toJSONString()); } /*** 重载一个异常的error** @param e*/publicvoiderror(Exceptione) { JSONObjectjsonObject=this.newJsonObject(); jsonObject.put("name", e.getClass().getName()); StringstackTrace=Arrays.toString(e.getStackTrace()); jsonObject.put("stackTrace", stackTrace); logger.error(jsonObject.toJSONString()); } privateJSONObjectnewJsonObject() { returnnewJSONObject(); } }
三、使用
Logger
对外提供了一个工厂LoggerFactory
,这里我们也提供一个JsonLoggerFactory
importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; publicclassJsonLoggerFactory { publicstaticJsonLoggergetJsonLogger(Class<?>clazz) { Loggerlogger=LoggerFactory.getLogger(clazz); returnnewJsonLogger(logger); } }
四、测试类
publicclassJsonLoggerTest { privatestaticfinalJsonLoggerlogger=JsonLoggerFactory.getJsonLogger(JsonLoggerTest.class); publicstaticvoidmain(String[] args) { logger.info("info日志"); logger.error("系统异常"); logger.error(newException("抛出异常")); } }
4.1 执行结果
10:30:31.368 [main] INFO com.example.validated.design.decorator.logger.JsonLoggerTest - {"message":"info日志"} 10:30:31.372 [main] ERROR com.example.validated.design.decorator.logger.JsonLoggerTest - {"message":"系统异常"} 10:30:31.372 [main] ERROR com.example.validated.design.decorator.logger.JsonLoggerTest - {"name":"java.lang.Exception","stackTrace":"[com.example.validated.design.decorator.logger.JsonLoggerTest.main(JsonLoggerTest.java:13)]"}
五、类图
六、其他
在实际的开发过程,我们也可以通过装饰器模式实现不同角色的用户去展示不同的导航菜单