前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring MVC旧项目的日志埋点

Spring MVC旧项目的日志埋点

作者头像
阿杜
发布2018-08-06 11:41:13
4360
发布2018-08-06 11:41:13
举报
文章被收录于专栏:阿杜的世界阿杜的世界

一、HTTP接口切面

  1. web容器和应用容器 IoC是Spring框架中的核心概念之一,如果要在Spring MVC中使用Spring的这一特性,也需要构建类似的容器。在Spring MVC中,主要通过web.xml进行Web相关的配置,例如配置DispatchServlet,以便应对url请求到具体的controller方法的映射。当DispatcherServlet启动的时候,它会创建一个对应的web应用上下文,负责加载web相关的组件,例如控制器、视图解析器以及处理器映射。在web.xml中,还有个常用配置:ContextLoaderListener,会创建一个Spring应用上下文,用于加载应用中的其他bean,例如各种Service、各种数据库访问层。借用官方文档-mvc servlet的一张图,可以看出,由ContextLoaderListener启动的容器为Root容器(父容器)、由DispatcherServlert启动的容器为Web容器(子容器),并且,子容器可以看到父容器中的bean,反之则不可。正是因为这个原因,在Controller层应用AOP技术的时候,要注意两点:(1)xxx-servlet.xml中的component-scan配置,要确定只扫描web组件、yyyyApplicationContext.xml中的component-scan配置,要排除掉web组件;(2)在xxx-servlet.xml中配置AOP,启动自动代理的配置为:<aop:aspectj-autoproxy proxy-target-class="true"/>,使用基于类的代理机制——CGLIB。

mvc-context-hierarchy

  1. 基于注解的AOP应用 我这里所谓基于注解的AOP技术,是指利用自定义注解标注要织入的切点,这种方式比较灵活,可以对指定接口中的某几个方法进行切面。例如,在这次处理日志埋点的需求中,我只给公开的接口加了注解:
代码语言:javascript
复制
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BizLogAnnotation {
    String description() default "";
}

然后在xxxAspect中给出如下切点定义即可:

代码语言:javascript
复制
@Aspect
@Component
public class DubboLogAspect {
    @Pointcut(value = "@annotation(com.xxxx.dubbo.log.BizLogAnnotation)")
    public void hsfMethod() { }
    ……
}
  1. 从切点JoinPoint获取注解中的描述信息,该方法参考自一文,代码如下:
代码语言:javascript
复制
public static String getControllerMethodDescription(JoinPoint joinPoint) throws Exception {  
        String targetName = joinPoint.getTarget().getClass().getName();  
        String methodName = joinPoint.getSignature().getName();  
        Object[] arguments = joinPoint.getArgs();  
        Class targetClass = Class.forName(targetName);  
        Method[] methods = targetClass.getMethods();  
        String description = "";  
        for (Method method : methods) {  
            if (method.getName().equals(methodName)) {  
                Class[] clazzs = method.getParameterTypes();  
                if (clazzs.length == arguments.length) {  
                    description = method.getAnnotation(SystemControllerLog.class).description();  
                    break;  
                }  
            }  
        }  
        return description;  
    }  

二、RPC服务接口切面

  1. 普通Service的AOP

三、Log4j日志配置

  1. 配置依赖,log4j + slf4j依赖
  2. 配置log4j.properties
  3. 修改代码中的Logger

四、补充资料

  1. 在阅读官方文档的时候,发现官方文档中也有对Controller AOP的阐述。

In some cases a controller may need to be decorated with an AOP proxy at runtime. One example is if you choose to have @Transactional annotations directly on the controller. When this is the case, for controllers specifically, we recommend using class-based proxying. This is typically the default choice with controllers. However if a controller must implement an interface that is not a Spring Context callback (e.g. InitializingBean, *Aware, etc), you may need to explicitly configure class-based proxying. For example with <tx:annotation-driven/>, change to <tx:annotation-driven proxy-target-class="true"/>.

  1. 为什么对Controller应用AOP的时候必须使用class-based的代理机制呢?这又涉及Spring中的两种代理机制:Java Proxy和CGLIB,Java Proxy要求被代理的类必须实现某个接口;CGLIB则属于基于子类的代理机制。参考What is the difference between JDK dynamic proxy and CGLib?
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.07.12 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、HTTP接口切面
  • 二、RPC服务接口切面
  • 三、Log4j日志配置
  • 四、补充资料
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档