统一的局部请求日志记录(即带注解的)
以下只是例子,给点不同的参考(日志其实在哪都能记)。没有绝对的好坏,只有适合的方案。
1、回顾:局部请求日志记录(@Addition)
这个是在另一个文里讲过的:《@Addition 用法说明(AOP)》
//定义日志处理
public class LoggingFilter implements Filter {
@Override
public void doFilter(Context ctx, FilterChain chain) throws Throwable {
chain.doFilter(ctx);
// aft do...
Action action = ctx.action();
//获取函数上的注解
Logging anno = action.method().getAnnotation(Logging.class);
if (anno == null) {
//如果没有尝试在控制器类上找注解
anno = action.controller().clz().getAnnotation(OptionLog.class);
}
if(anno != null){
//如果有打印下(理论上都会有,但避免被拿去乱话)
System.out.println((String) ctx.attr("output"));
}
}
}
//定义注解
@Addition(LoggingFilter.class)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Logging {
}
//应用
@Controller
public class DemoController{
@Logging
@Mapping("user/del")
public void delUser(..){
}
}
2、使用 RouterInterceptor 方案
@Addition
能干的事儿,RouterInterceptor 都能干。 这个方案,多个计时功能。如果全局都记,可以去掉注解检查(或者检查别的注解)。
//定义注解(少了 @After)
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Logging {
}
//定义路由拦截器(放到外层一点)//环绕处理,越小越外层
@Component(index = -99)
public class LoggingRouterInterceptor implements RouterInterceptor {
@Override
public void doIntercept(Context ctx, Handler mainHandler, RouterInterceptorChain chain) throws Throwable {
Loggging anno = null;
Action action = ctx.action();
if (action != null) {
anno = action.method().getAnnotation(Loggging.class);
}
if (anno == null) {
//如果没有注解
chain.doIntercept(ctx, mainHandler);
} else {
//1.开始计时
long start = System.currentTimeMillis();
try {
chain.doIntercept(ctx, mainHandler);
} finally {
//2.获得接口响应时长
long timespan = System.currentTimeMillis() - start;
//3.记日志
System.out.println("用时:" + timespan);
}
}
}
}
//应用
@Controller
public class DemoController{
@Logging
@Mapping("user/del")
public void delUser(..){
}
}