zoukankan      html  css  js  c++  java
  • aspectj-autoproxy Controller未生效解决方案

     本周做业务需求,需要对api的响应时间做监控。第一想法是在需要监控的api里面答应日志,记录care的信息,这样的最大问题就是不容易扩展,需要在每个api里面添加几乎相同的代码。当时,Java的通用做法是切片,利用Java语言提供的反射能力,结合spring 的三大特性之一的aop(面向切面编程)思想,可以完全解耦的添加切片就行,这样在低耦合、高内聚的编程原则下是显得比较优雅,但是难免要牺牲一下效率,反射是对象运行时动态特性,需要消耗额外的性能。想到之前没有独立在工程里引入切片,同时保持代码的优雅,决定是切片。

    步骤

    1、业务切片代码  


    @Aspect
    @Component
    public class ApiAspect {


    @Around("execution (* com.jinxu.api..*.*(..))")
    public Object apiLog(ProceedingJoinPoint joinPoint) throws Throwable {
    Long startTime = 0l;
    Long endTime = 0l;
    Object result = null;
    try {
    startTime = System.currentTimeMillis();
    result = joinPoint.proceed();
    endTime=System.currentTimeMillis();
    } catch (Exception e) {
    throw e;
    } finally {
    try {
    Object[] args = joinPoint.getArgs();
    Object object = args[0];
    if (object instanceof HttpServletRequest) {
    object = ((HttpServletRequest) object).getParameterMap();
    }
    String method = joinPoint.getSignature().getName();
    String request = JsonUtils.json(object);//此处注意json与非json的对应关系
    String response = JsonUtils.json(result);//
    logger.debug(String.format("method:%s" + " - request:%s" + " - response:%s" + " - cost:%s", method, request, response, endTime - startTime));
    } catch (Exception e) {
    logger.error("com.jinxu.api包切片异常,但是不影响正常业务:" + e);
    }
    }
    return result;
    }
    }
     需要引入的jar包如下:

    <dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    </dependency>
    <dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib-nodep</artifactId>
    </dependency>
      其中cglib是运行期扩展Java类与实现Java接口的代码,也就是jdk反射的扩展,一般用它替换jdk自带的更可用。
    2、配置spring加载文件

    <!-- AOP -->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
      其中可以加载代码中有@Aspect标签的切片,proxy-target-class属性值决定是接口的还是类的代理被创建。如果proxy-target-class 属性值被设置为true,那么类的代理将起作用,如cglib库;如果proxy-target-class属值被设置为false或者这个属性被省略,那么标准的JDK基于接口的代理。当时,如果没有对应接口,只有实现,类的代理将起作用。

    3、问题

      关于切片的使用,其他工程和网上的资料确实比较多,于是直接配置了。结果发现但是实际Controller切片并未生效,aop切片没有被执行到。一般情况下,模仿其他配置,放在applicationContext.xml里面,是会起作用的,于是查了很多资料,对比其他工程,没有实质收获。

      The aspects and the beans to be applied needs to be in the same ApplicationContext but ApplicationContext is not aware of

     WebApplicationContext . 
      Indeed your controller (annotated by @Controller) and your aspects (annotated by @Aspect) should be in the same Spring context. 

      Usually people define their controllers in the dispatch-servlet.xml or xxx-servlet.xml and their service beans (including the aspects) in the

     main applicationContext.xml. It will not work. 

      When Spring initializes the MVC context, it will create a proxy for your controller but if your aspects are not in the same context, Spring will not create interceptors for them. 

      翻译过来就是Controller是定义在xxx-servlet.xml配置文件中,所以定义在applicationContext.xml中的aspects切片并不会生效,需要将aspects定义转移到xxx-servlet.xml文件中。修改过来问题就解决了,大家如果遇到可以参考上面简陋的解决步骤。

    参考资料:https://www.iteye.com/blog/jinnianshilongnian-1901694

  • 相关阅读:
    Codeforces Round #592 (Div. 2)C. The Football Season(暴力,循环节)
    Educational Codeforces Round 72 (Rated for Div. 2)D. Coloring Edges(想法)
    扩展KMP
    poj 1699 Best Sequence(dfs)
    KMP(思路分析)
    poj 1950 Dessert(dfs)
    poj 3278 Catch That Cow(BFS)
    素数环(回溯)
    sort与qsort
    poj 1952 buy low buy lower(DP)
  • 原文地址:https://www.cnblogs.com/sidesky/p/12717832.html
Copyright © 2011-2022 走看看