• 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

  • 相关阅读:
    WSS基础
    SPCAMLEditor1.0 publish
    关于代码调用SSP获取UserProfile出错的解决方案
    WSS Alert(邮件提醒) 定制
    MOSS字段编辑权限控制方案发布源码
    ListViewWebPart Code
    再议WSS RenderingTemplate
    Windows SharePoint Services Search和Office SharePoint Server Search的区别
    MOSS信息管理策略定制(MOSS custom policies)
    发布一个小工具SPCamlEditor
  • 原文地址:https://www.cnblogs.com/sidesky/p/12717832.html
Copyright © 2020-2023  润新知