SpringAOP拦截Controller,Service实现日志管理(自定义注解的方式)

本文展示了如何使用Spring AOP通过自定义注解的方式实现对Controller和服务层的方法进行日志管理。详细介绍了如何定义切点、注解、切面,并提供了拦截Controller和Service的方法,记录用户的操作日志和异常信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  1. package com.wssys.framework;  
  2.   
  3. import java.lang.reflect.Method;  
  4. import java.text.SimpleDateFormat;  
  5. import java.util.Calendar;  
  6.   
  7. import javax.servlet.http.HttpServletRequest;  
  8. import org.apache.shiro.SecurityUtils;  
  9. import org.aspectj.lang.ProceedingJoinPoint;  
  10. import org.aspectj.lang.annotation.Around;  
  11. import org.aspectj.lang.annotation.Aspect;  
  12. import org.aspectj.lang.annotation.Pointcut;  
  13. import org.springframework.beans.factory.annotation.Autowired;  
  14. import org.springframework.stereotype.Component;  
  15. import org.springframework.web.context.request.RequestContextHolder;  
  16. import org.springframework.web.context.request.ServletRequestAttributes;  
  17.   
  18. import com.wssys.bean.BolBean;  
  19. import com.wssys.bean.ComPanyForm;  
  20. import com.wssys.bean.DeliverBean;  
  21. import com.wssys.bean.GoodsForm;  
  22. import com.wssys.dao.SyslogDao;  
  23. import com.wssys.entity.Companycontacts;  
  24. import com.wssys.entity.PusFrontUser;  
  25. import com.wssys.entity.PusMenu;  
  26. import com.wssys.entity.PusRole;  
  27. import com.wssys.entity.PusSysUser;  
  28. import com.wssys.entity.Syslog;  
  29. import com.wssys.utils.StringUtil;  
  30. import com.wssys.utils.TCPIPUtil;  
  31.   
  32. /** 
  33.  * \ 
  34.  *  
  35.  * @Aspect 实现spring aop 切面(Aspect): 
  36.  *         一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring 
  37.  *         AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。 
  38.  *  
  39.  *         AOP代理(AOP Proxy): AOP框架创建的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 
  40.  *         在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。 注意:Spring 
  41.  *         2.0最新引入的基于模式(schema-based 
  42.  *         )风格和@AspectJ注解风格的切面声明,对于使用这些风格的用户来说,代理的创建是透明的。 
  43.  * @author q 
  44.  *  
  45.  */  
  46. @Component  
  47. @Aspect  
  48. public class LogService {  
  49.   
  50.     @Autowired  
  51.     private SyslogDao syslogDao;  
  52.   
  53.     public LogService() {  
  54.         System.out.println("Aop");  
  55.     }  
  56.   
  57.     /** 
  58.      * 在Spring 
  59.      * 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature 
  60.      * )。让我们先看看execution表示式的格式: 
  61.      * 括号中各个pattern分别表示修饰符匹配(modifier-pattern?)、返回值匹配(ret 
  62.      * -type-pattern)、类路径匹配(declaring 
  63.      * -type-pattern?)、方法名匹配(name-pattern)、参数匹配((param 
  64.      * -pattern))、异常类型匹配(throws-pattern?),其中后面跟着“?”的是可选项。 
  65.      *  
  66.      * @param point 
  67.      * @throws Throwable 
  68.      */  
  69.   
  70.     @Pointcut("@annotation(com.wssys.framework.MethodLog)")  
  71.     public void methodCachePointcut() {  
  72.   
  73.     }  
  74.   
  75.     // // @Before("execution(* com.wssys.controller.*(..))")  
  76.     // public void logAll(JoinPoint point) throws Throwable {  
  77.     // System.out.println("打印========================");  
  78.     // }  
  79.     //  
  80.     // // @After("execution(* com.wssys.controller.*(..))")  
  81.     // public void after() {  
  82.     // System.out.println("after");  
  83.     // }  
  84.   
  85.     // 方法执行的前后调用  
  86.     // @Around("execution(* com.wssys.controller.*(..))||execution(* com.bpm.*.web.account.*.*(..))")  
  87.     // @Around("execution(* com.wssys.controller.*(..))")  
  88.     // @Around("execution(* org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(..))")  
  89.     @Around("methodCachePointcut()")  
  90.     public Object around(ProceedingJoinPoint point) throws Throwable {  
  91.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder  
  92.                 .getRequestAttributes()).getRequest();  
  93.         SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E");  
  94.         Calendar ca = Calendar.getInstance();  
  95.         String operDate = df.format(ca.getTime());  
  96.         String ip = TCPIPUtil.getIpAddr(request);  
  97.         PusSysUser user = (PusSysUser) SecurityUtils.getSubject()  
  98.                 .getPrincipal();  
  99.         String loginName;  
  100.         String name;  
  101.         if (user != null) {  
  102.             loginName = user.getAccount();  
  103.             // name = user.name;  
  104.         } else {  
  105.             loginName = "匿名用户";  
  106.             // name = "匿名用户";  
  107.         }  
  108.   
  109.         String monthRemark = getMthodRemark(point);  
  110.         String monthName = point.getSignature().getName();  
  111.         String packages = point.getThis().getClass().getName();  
  112.         if (packages.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB动态生成的类  
  113.             try {  
  114.                 packages = packages.substring(0, packages.indexOf("$$"));  
  115.             } catch (Exception ex) {  
  116.                 ex.printStackTrace();  
  117.             }  
  118.         }  
  119.   
  120.         String operatingcontent = "";  
  121.         Object[] method_param = null;  
  122.   
  123.         Object object;  
  124.         try {  
  125.             method_param = point.getArgs(); //获取方法参数   
  126.             // String param=(String) point.proceed(point.getArgs());  
  127.             object = point.proceed();  
  128.         } catch (Exception e) {  
  129.             // 异常处理记录日志..log.error(e);  
  130.             throw e;  
  131.         }  
  132.         Syslog sysLog = new Syslog();  
  133.         sysLog.setIpAddress(ip);  
  134.         sysLog.setLoginName(loginName);  
  135.         sysLog.setMethodName(packages + "." + monthName);  
  136.         sysLog.setMethodRemark(monthRemark);  
  137.         //这里有点纠结 就是不好判断第一个object元素的类型 只好通过  方法描述来 做一一  转型感觉 这里 有点麻烦 可能是我对 aop不太了解  希望懂的高手在回复评论里给予我指点  
  138.         //有没有更好的办法来记录操作参数  因为参数会有 实体类 或者javabean这种参数怎么把它里面的数据都解析出来?  
  139.         if (StringUtil.stringIsNull(monthRemark).equals("会员新增")) {  
  140.             PusFrontUser pfu = (PusFrontUser) method_param[0];  
  141.             sysLog.setOperatingcontent("新增会员:" + pfu.getAccount());  
  142.         } else if (StringUtil.stringIsNull(monthRemark).equals("新增角色")) {  
  143.             PusRole pr = (PusRole) method_param[0];  
  144.             sysLog.setOperatingcontent("新增角色:" + pr.getName());  
  145.         } else if (StringUtil.stringIsNull(monthRemark).equals("用户登录")) {  
  146.             PusSysUser currUser = (PusSysUser) method_param[0];  
  147.             sysLog.setOperatingcontent("登录帐号:" + currUser.getAccount());  
  148.         } else if (StringUtil.stringIsNull(monthRemark).equals("用户退出")) {  
  149.             sysLog.setOperatingcontent("具体请查看用户登录日志");  
  150.         } else if (StringUtil.stringIsNull(monthRemark).equals("角色名称修改")) {  
  151.             PusRole pr = (PusRole) method_param[0];  
  152.             sysLog.setOperatingcontent("修改角色:" + pr.getName());  
  153.         } else if (StringUtil.stringIsNull(monthRemark).equals("新增后台用户")) {  
  154.             PusSysUser psu = (PusSysUser) method_param[0];  
  155.             sysLog.setOperatingcontent("新增后台用户:" + psu.getAccount());  
  156.         } else if (StringUtil.stringIsNull(monthRemark).equals("更新菜单")) {  
  157.             PusMenu pm = (PusMenu) method_param[0];  
  158.             sysLog.setOperatingcontent("更新菜单:" + pm.getName());  
  159.         } else if (StringUtil.stringIsNull(monthRemark).equals("保存菜单")) {  
  160.             PusMenu pm = (PusMenu) method_param[0];  
  161.             sysLog.setOperatingcontent("保存菜单:" + pm.getName());  
  162.         } else if (StringUtil.stringIsNull(monthRemark).equals("修改公司")) {  
  163.             ComPanyForm ciform = (ComPanyForm) method_param[0];  
  164.             sysLog.setOperatingcontent("修改公司:" + ciform.getName());  
  165.         } else if (StringUtil.stringIsNull(monthRemark).equals("联系人更新")) {  
  166.             Companycontacts ct = (Companycontacts) method_param[0];  
  167.             sysLog.setOperatingcontent("联系人更新:" + ct.getName());  
  168.         } else if (StringUtil.stringIsNull(monthRemark).equals("修改货物")) {  
  169.             GoodsForm goodsForm = (GoodsForm) method_param[0];  
  170.             sysLog.setOperatingcontent("修改货物(货物id/编号):" + goodsForm.getId());  
  171.         } else if (StringUtil.stringIsNull(monthRemark).equals("打印出库单")) {  
  172.             DeliverBean owh= (DeliverBean) method_param[0];  
  173.             sysLog.setOperatingcontent("出库单单号:" + owh.getCknum());  
  174.         } else if (StringUtil.stringIsNull(monthRemark).equals("打印提单")) {  
  175.             BolBean bol= (BolBean) method_param[0];  
  176.             sysLog.setOperatingcontent("提货单号:" + bol.getBolnum());  
  177.         } else if (StringUtil.stringIsNull(monthRemark).equals("系统左侧菜单查询")) {  
  178.             sysLog.setOperatingcontent("无");  
  179.         } else {  
  180.             sysLog.setOperatingcontent("操作参数:" + method_param[0]);  
  181.         }  
  182.   
  183.         syslogDao.save(sysLog);  
  184.         return object;  
  185.     }  
  186.   
  187.     // 方法运行出现异常时调用    
  188.     // @AfterThrowing(pointcut = "execution(* com.wssys.controller.*(..))",  
  189.     // throwing = "ex")  
  190.     public void afterThrowing(Exception ex) {  
  191.         System.out.println("afterThrowing");  
  192.         System.out.println(ex);  
  193.     }  
  194.   
  195.     // 获取方法的中文备注____用于记录用户的操作日志描述  
  196.     public static String getMthodRemark(ProceedingJoinPoint joinPoint)  
  197.             throws Exception {  
  198.         String targetName = joinPoint.getTarget().getClass().getName();  
  199.         String methodName = joinPoint.getSignature().getName();  
  200.         Object[] arguments = joinPoint.getArgs();  
  201.   
  202.         Class targetClass = Class.forName(targetName);  
  203.         Method[] method = targetClass.getMethods();  
  204.         String methode = "";  
  205.         for (Method m : method) {  
  206.             if (m.getName().equals(methodName)) {  
  207.                 Class[] tmpCs = m.getParameterTypes();  
  208.                 if (tmpCs.length == arguments.length) {  
  209.                     MethodLog methodCache = m.getAnnotation(MethodLog.class);  
  210.                     if (methodCache != null) {  
  211.                         methode = methodCache.remark();  
  212.                     }  
  213.                     break;  
  214.                 }  
  215.             }  
  216.         }  
  217.         return methode;  
  218.     }  
  219.   
  220.   
  221. }  




spring application.xml配置: 

  <!-- aop --> 
  <bean id="logService" class="com.wssys.framework.LogService"></bean> 

   <!-- 启动对@AspectJ注解的支持  --> 
   <aop:aspectj-autoproxy proxy-target-class="true" /> 


spring mvc controller层action的 
设置 例如: 

Java代码   收藏代码
  1. @RequestMapping(value = "/addFrontUser", method = RequestMethod.POST)  
  2. @MethodLog(remark = "会员新增")  
  3. public String saveFrontUserAction(@ModelAttribute("psu") PusFrontUser pfu,  
  4.         BindingResult result, SessionStatus status,  
  5.         HttpServletResponse response) {  
  6.     if (pusFrontUserDao.checkAccount(pfu.getAccount()) > 0) {  
  7.         PrintWriter out = null;  
  8.         try {  
  9.             out = response.getWriter();  
  10.         } catch (IOException e) {  
  11.             // TODO Auto-generated catch block  
  12.             e.printStackTrace();  
  13.         }  
  14.   
  15.         out.write("保存失败,会员帐号已经存在");  
  16.   
  17.         out.flush();  
  18.         return null;  
  19.     }  
  20.     // Timestamp now = new Timestamp(System.currentTimeMillis());// 获取系统当前时间  
  21.   
  22.     int saverec = 0;  
  23.   
  24.     pfu.setPwd(new Sha384Hash(pfu.getPwd()).toBase64());  
  25.     saverec = pusFrontUserDao.save(pfu);  
  26.   
  27.     PrintWriter out = null;  
  28.     try {  
  29.         out = response.getWriter();  
  30.     } catch (IOException e) {  
  31.         // TODO Auto-generated catch block  
  32.         e.printStackTrace();  
  33.     }  
  34.     if (saverec > 0) {  
  35.         out.write("保存成功,您可以继续保存或者关闭当前页面");  
  36.     } else {  
  37.         out.write("保存失败");  
  38.     }  
  39.   
  40.     out.flush();  
  41.     return null;  
  42. }  




Java代码   收藏代码
  1. package com.wssys.framework;  
  2.   
  3. import java.lang.annotation.Documented;  
  4. import java.lang.annotation.ElementType;  
  5. import java.lang.annotation.Retention;  
  6. import java.lang.annotation.RetentionPolicy;  
  7. import java.lang.annotation.Target;  
  8.   
  9. /** 
  10.  * 表示对标记有xxx注解的类,做代理 注解@Retention可以用来修饰注解,是注解的注解,称为元注解。 
  11.  * Retention注解有一个属性value,是RetentionPolicy类型的,Enum RetentionPolicy是一个枚举类型, 
  12.  * 这个枚举决定了Retention注解应该如何去保持,也可理解为Rentention 搭配 
  13.  * RententionPolicy使用。RetentionPolicy有3个值:CLASS RUNTIME SOURCE 
  14.  * 用@Retention(RetentionPolicy 
  15.  * .CLASS)修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,但不会被虚拟机读取在运行的时候; 
  16.  * 用@Retention(RetentionPolicy.SOURCE 
  17.  * )修饰的注解,表示注解的信息会被编译器抛弃,不会留在class文件中,注解的信息只会留在源文件中; 
  18.  * 用@Retention(RetentionPolicy.RUNTIME 
  19.  * )修饰的注解,表示注解的信息被保留在class文件(字节码文件)中当程序编译时,会被虚拟机保留在运行时, 
  20.  * 所以他们可以用反射的方式读取。RetentionPolicy.RUNTIME 
  21.  * 可以让你从JVM中读取Annotation注解的信息,以便在分析程序的时候使用. 
  22.  *  
  23.  * 类和方法的annotation缺省情况下是不出现在javadoc中的,为了加入这个性质我们用@Documented 
  24.  *  java用  @interface Annotation{ } 定义一个注解 @Annotation,一个注解是一个类。 
  25.  *  @interface是一个关键字,在设计annotations的时候必须把一个类型定义为@interface,而不能用class或interface关键字  
  26.  *  
  27.  * @author q 
  28.  *  
  29.  */  
  30.   
  31. @Target({ ElementType.METHOD, ElementType.TYPE })  
  32. @Retention(RetentionPolicy.RUNTIME)  
  33. @Documented  
  34. public @interface MethodLog {  
  35. String remark() default "";  
  36.     String operType() default "0";     
  37.    // String desc() default "";  
  38. }  


日志 数据效果: 



=========【参考2】========

 从业近二,三年了,第一次写博客,平时做做脚手架或者架构一些基础框架然后给大家使用或者自己总结翻译一些文档。虽然是第一次但是我还是要拿Spring开刀。希望张开涛,涛兄看到的时候不要喷我,给我一点指导。

         首先我们为什么需要做日志管理,在现实的上线中我们经常会遇到系统出现异常或者问题。这个时候就马上打开CRT或者SSH连上服务器拿日子来分析。受网络的各种限制。于是我们就想为什么不能直接在管理后台查看报错的信息呢。于是日志管理就出现了。

         其次个人觉得做日志管理最好的是Aop,有的人也喜欢用拦截器。都可以,在此我重点介绍我的实现方式。

         Aop有的人说拦截不到Controller。有的人说想拦AnnotationMethodHandlerAdapter截到Controller必须得拦截org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter。

首先Aop可以拦截到Controller的,这个是毋容置疑的其次须拦截AnnotationMethodHandlerAdapter也不是必须的。最起码我没有验证成功过这个。我的Spring版本是4.0.3。

         Aop之所以有的人说拦截不到Controller是因为Controller被jdk代理了。我们只要把它交给cglib代理就可以了。

第一步定义两个注解:

 

Java代码  复制代码
  1. package com.annotation;  
  2.   
  3. import java.lang.annotation.*;  
  4.   
  5. /** 
  6.  *自定义注解 拦截Controller 
  7.  */  
  8.   
  9. @Target({ElementType.PARAMETER, ElementType.METHOD})  
  10. @Retention(RetentionPolicy.RUNTIME)  
  11. @Documented  
  12. public  @interface SystemControllerLog {  
  13.   
  14.     String description()  default "";  
  15.   
  16.   
  17. }  
  18.   
  19. package com.annotation;  
  20.   
  21. import java.lang.annotation.*;  
  22.   
  23. /** 
  24.  *自定义注解 拦截service 
  25.  */  
  26.   
  27. @Target({ElementType.PARAMETER, ElementType.METHOD})  
  28. @Retention(RetentionPolicy.RUNTIME)  
  29. @Documented  
  30. public  @interface SystemServiceLog {  
  31.   
  32.     String description()  default "";  
  33.   
  34.   
  35. }  

第二步创建一个切点类:

 

 

Java代码  复制代码
  1. package com.annotation;  
  2.   
  3. import com.model.Log;  
  4. import com.model.User;  
  5. import com.service.LogService;  
  6. import com.util.DateUtil;  
  7. import com.util.JSONUtil;  
  8. import com.util.SpringContextHolder;  
  9. import com.util.WebConstants;  
  10. import org.aspectj.lang.JoinPoint;  
  11. import org.aspectj.lang.annotation.*;  
  12. import org.slf4j.Logger;  
  13. import org.slf4j.LoggerFactory;  
  14. import org.springframework.stereotype.Component;  
  15. import org.springframework.web.context.request.RequestContextHolder;  
  16. import org.springframework.web.context.request.ServletRequestAttributes;  
  17. import javax.annotation.Resource;  
  18. import javax.servlet.http.HttpServletRequest;  
  19. import javax.servlet.http.HttpSession;  
  20. import java.lang.reflect.Method;  
  21.   
  22. /** 
  23.  * 切点类 
  24.  * @author tiangai 
  25.  * @since 2014-08-05 Pm 20:35 
  26.  * @version 1.0 
  27.  */  
  28. @Aspect  
  29. @Component  
  30. public  class SystemLogAspect {  
  31.     //注入Service用于把日志保存数据库  
  32.     @Resource  
  33.      private LogService logService;  
  34.     //本地异常日志记录对象  
  35.      private  static  final Logger logger = LoggerFactory.getLogger(SystemLogAspect. class);  
  36.   
  37.     //Service层切点  
  38.     @Pointcut("@annotation(com.annotation.SystemServiceLog)")  
  39.      public  void serviceAspect() {  
  40.     }  
  41.   
  42.     //Controller层切点  
  43.     @Pointcut("@annotation(com.annotation.SystemControllerLog)")  
  44.      public  void controllerAspect() {  
  45.     }  
  46.   
  47.     /** 
  48.      * 前置通知 用于拦截Controller层记录用户的操作 
  49.      * 
  50.      * @param joinPoint 切点 
  51.      */  
  52.     @Before("controllerAspect()")  
  53.      public  void doBefore(JoinPoint joinPoint) {  
  54.   
  55.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  
  56.         HttpSession session = request.getSession();  
  57.         //读取session中的用户  
  58.         User user = (User) session.getAttribute(WebConstants.CURRENT_USER);  
  59.         //请求的IP  
  60.         String ip = request.getRemoteAddr();  
  61.          try {  
  62.             //*========控制台输出=========*//  
  63.             System.out.println("=====前置通知开始=====");  
  64.             System.out.println("请求方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
  65.             System.out.println("方法描述:" + getControllerMethodDescription(joinPoint));  
  66.             System.out.println("请求人:" + user.getName());  
  67.             System.out.println("请求IP:" + ip);  
  68.             //*========数据库日志=========*//  
  69.             Log log = SpringContextHolder.getBean("logxx");  
  70.             log.setDescription(getControllerMethodDescription(joinPoint));  
  71.             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
  72.             log.setType("0");  
  73.             log.setRequestIp(ip);  
  74.             log.setExceptionCode( null);  
  75.             log.setExceptionDetail( null);  
  76.             log.setParams( null);  
  77.             log.setCreateBy(user);  
  78.             log.setCreateDate(DateUtil.getCurrentDate());  
  79.             //保存数据库  
  80.             logService.add(log);  
  81.             System.out.println("=====前置通知结束=====");  
  82.         }  catch (Exception e) {  
  83.             //记录本地异常日志  
  84.             logger.error("==前置通知异常==");  
  85.             logger.error("异常信息:{}", e.getMessage());  
  86.         }  
  87.     }  
  88.   
  89.     /** 
  90.      * 异常通知 用于拦截service层记录异常日志 
  91.      * 
  92.      * @param joinPoint 
  93.      * @param e 
  94.      */  
  95.     @AfterThrowing(pointcut = "serviceAspect()", throwing = "e")  
  96.      public  void doAfterThrowing(JoinPoint joinPoint, Throwable e) {  
  97.         HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();  
  98.         HttpSession session = request.getSession();  
  99.         //读取session中的用户  
  100.         User user = (User) session.getAttribute(WebConstants.CURRENT_USER);  
  101.         //获取请求ip  
  102.         String ip = request.getRemoteAddr();  
  103.         //获取用户请求方法的参数并序列化为JSON格式字符串  
  104.         String params = "";  
  105.          if (joinPoint.getArgs() !=  null && joinPoint.getArgs().length > 0) {  
  106.              for ( int i = 0; i < joinPoint.getArgs().length; i++) {  
  107.                 params += JSONUtil.toJsonString(joinPoint.getArgs()[i]) + ";";  
  108.             }  
  109.         }  
  110.          try {  
  111.               /*========控制台输出=========*/  
  112.             System.out.println("=====异常通知开始=====");  
  113.             System.out.println("异常代码:" + e.getClass().getName());  
  114.             System.out.println("异常信息:" + e.getMessage());  
  115.             System.out.println("异常方法:" + (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
  116.             System.out.println("方法描述:" + getServiceMthodDescription(joinPoint));  
  117.             System.out.println("请求人:" + user.getName());  
  118.             System.out.println("请求IP:" + ip);  
  119.             System.out.println("请求参数:" + params);  
  120.                /*==========数据库日志=========*/  
  121.             Log log = SpringContextHolder.getBean("logxx");  
  122.             log.setDescription(getServiceMthodDescription(joinPoint));  
  123.             log.setExceptionCode(e.getClass().getName());  
  124.             log.setType("1");  
  125.             log.setExceptionDetail(e.getMessage());  
  126.             log.setMethod((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()"));  
  127.             log.setParams(params);  
  128.             log.setCreateBy(user);  
  129.             log.setCreateDate(DateUtil.getCurrentDate());  
  130.             log.setRequestIp(ip);  
  131.             //保存数据库  
  132.             logService.add(log);  
  133.             System.out.println("=====异常通知结束=====");  
  134.         }  catch (Exception ex) {  
  135.             //记录本地异常日志  
  136.             logger.error("==异常通知异常==");  
  137.             logger.error("异常信息:{}", ex.getMessage());  
  138.         }  
  139.          /*==========记录本地异常日志==========*/  
  140.         logger.error("异常方法:{}异常代码:{}异常信息:{}参数:{}", joinPoint.getTarget().getClass().getName() + joinPoint.getSignature().getName(), e.getClass().getName(), e.getMessage(), params);  
  141.   
  142.     }  
  143.   
  144.   
  145.     /** 
  146.      * 获取注解中对方法的描述信息 用于service层注解 
  147.      * 
  148.      * @param joinPoint 切点 
  149.      * @return 方法描述 
  150.      * @throws Exception 
  151.      */  
  152.      public  static String getServiceMthodDescription(JoinPoint joinPoint)  
  153.              throws Exception {  
  154.         String targetName = joinPoint.getTarget().getClass().getName();  
  155.         String methodName = joinPoint.getSignature().getName();  
  156.         Object[] arguments = joinPoint.getArgs();  
  157.         Class targetClass = Class.forName(targetName);  
  158.         Method[] methods = targetClass.getMethods();  
  159.         String description = "";  
  160.          for (Method method : methods) {  
  161.              if (method.getName().equals(methodName)) {  
  162.                 Class[] clazzs = method.getParameterTypes();  
  163.                  if (clazzs.length == arguments.length) {  
  164.                     description = method.getAnnotation(SystemServiceLog. class).description();  
  165.                      break;  
  166.                 }  
  167.             }  
  168.         }  
  169.          return description;  
  170.     }  
  171.   
  172.     /** 
  173.      * 获取注解中对方法的描述信息 用于Controller层注解 
  174.      * 
  175.      * @param joinPoint 切点 
  176.      * @return 方法描述 
  177.      * @throws Exception 
  178.      */  
  179.      public  static String getControllerMethodDescription(JoinPoint joinPoint)  throws Exception {  
  180.         String targetName = joinPoint.getTarget().getClass().getName();  
  181.         String methodName = joinPoint.getSignature().getName();  
  182.         Object[] arguments = joinPoint.getArgs();  
  183.         Class targetClass = Class.forName(targetName);  
  184.         Method[] methods = targetClass.getMethods();  
  185.         String description = "";  
  186.          for (Method method : methods) {  
  187.              if (method.getName().equals(methodName)) {  
  188.                 Class[] clazzs = method.getParameterTypes();  
  189.                  if (clazzs.length == arguments.length) {  
  190.                     description = method.getAnnotation(SystemControllerLog. class).description();  
  191.                      break;  
  192.                 }  
  193.             }  
  194.         }  
  195.          return description;  
  196.     }  
  197. }  

 第三步把Controller的代理权交给cglib

 

在实例化ApplicationContext的时候需要加上

 

Xml代码  复制代码
  1. <!-- 启动对@AspectJ注解的支持 -->  
  2. <aop:aspectj-autoproxy/>  

 在调用Controller的时候AOP发挥作用所以在SpringMVC的配置文件里加上

 

 

Xml代码  复制代码
  1. <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller->  
  2. <aop:aspectj-autoproxy proxy-target-class="true" />  

 第四步使用

 

Controller层的使用

 

Java代码  复制代码
  1. /** 
  2.     * 删除用户 
  3.     * 
  4.     * @param criteria 条件 
  5.     * @param id       id 
  6.     * @param model    模型 
  7.     * @return 数据列表 
  8.     */  
  9.    @RequestMapping(value = "/delete")  
  10.    //此处为记录AOP拦截Controller记录用户操作  
  11.    @SystemControllerLog(description = "删除用户")  
  12.     public String del(Criteria criteria, String id, Model model, HttpSession session) {  
  13.         try {  
  14.            User user = (User) session.getAttribute(WebConstants.CURRENT_USER);  
  15.             if ( null != user) {  
  16.                 if (user.getId().equals(id)) {  
  17.                    msg = "您不可以删除自己!";  
  18.                    criteria = userService.selectByCriteriaPagination(criteria);  
  19.                }  else {  
  20.                    //删除数据并查询出数据  
  21.                    criteria = userService.delete(id, criteria);  
  22.                    msg = "删除成功!";  
  23.                }  
  24.            }  
  25.        }  catch (Exception e) {  
  26.            msg = "删除失败!";  
  27.        }  finally {  
  28.            model.addAttribute("msg", msg);  
  29.            model.addAttribute("criteria", criteria);  
  30.        }  
  31.        //跳转列表页  
  32.         return "user/list";  
  33.    }  

 Service层的使用

 

 

Java代码  复制代码
  1. /** 
  2.     * 按照分页查询 
  3.     * @param criteria 
  4.     * @return 
  5.     */  
  6.    //此处为AOP拦截Service记录异常信息。方法不需要加try-catch  
  7.    @SystemServiceLog(description = "查询用户")  
  8.     public Criteria<User> selectByCriteriaPagination(Criteria<User> criteria)  
  9.    {  
  10.        criteria.getList().get(0).getAccount();  
  11.        //查询总数  
  12.         long total=userMapper.countByCriteria(criteria);  
  13.        //设置总数  
  14.        criteria.setRowCount(total);  
  15.        criteria.setList(userMapper.selectByCriteriaPagination(criteria));  
  16.         return  criteria;  
  17.    }  

效果图

 

用户操作:



 异常



 初次写博客,写的不好敬请见谅



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值