springAOP注解方式实现日志操作
通过自定义注解调用方法执行日志存储:
package com.zktx.platform.log2; import java.lang.reflect.Method; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import com.zktx.platform.entity.tb.logInfo; import com.zktx.platform.entity.tb.user.ShiroUser; import com.zktx.platform.service.log.LogService; import com.zktx.platform.shiro.SecurityUtils; /** * * 首先我们为什么需要做日志管理,在现实的上线中我们经常会遇到系统出现异常或者问题。 这个时候就马上打开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代理就可以了 * * <!-- 启动对@AspectJ注解的支持 --> <aop:aspectj-autoproxy /> * <!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller--> * <aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy> * <!-- 节点中proxy-target-class="true"不为true时。 * * 当登录的时候会报这个异常java.lang.NoSuchMethodException: $Proxy54.login(), --> * <aop:config proxy-target-class="true"></aop:config> * * 创建一个切点类 * * @author Administrator * */ @Aspect @Component public class SystemLogAspect { // 本地异常日志记录对象 private static final Logger log = LoggerFactory.getLogger(SystemLogAspect.class); @Autowired LogService logService; @Autowired private HttpServletRequest request; // Controller层切点 @Pointcut("@annotation(com.zktx.platform.log2.SystemControllerLog)") public void controllerAspect() { } @After(value = "controllerAspect()") public void doAfter(JoinPoint joinPoint) { // 这里获取request;千万不要写在下边的线程里,因为得不到 HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); System.out.println(request.getAttribute("message") + "======="); new Thread(new Runnable() { @Override public void run() { try { // log.info("进入日志系统————————————" + request.getLocalAddr()); logInfo info = new logInfo(); String description = getControllerMethodDescription(joinPoint); ShiroUser user = SecurityUtils.getShiroUser(); info.setUser_name(user.getName()); info.setMessage(description); info.setIp_address(user.getIpAddress()); info.setCreate_time(new Date()); logService.insertLogInfo(info); } catch (Exception e) { e.printStackTrace(); } } }).start(); } // 可以得到方法return的值 @AfterReturning(returning = "ret", pointcut = "controllerAspect()") public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 System.out.println(ret); Map<String, Object> map = (Map<String, Object>) ret; System.out.println(map.get("total")); } // 通过反射获取参入的参数 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); String description = ""; Method[] methods = targetClass.getMethods(); 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; } }
定义注解:
package com.zktx.platform.log2; /** * 自定义注解,拦截Controller */ import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD, ElementType.PARAMETER }) @Documented public @interface SystemControllerLog { String description() default ""; }
使用方式:
// 条件查询 @SystemControllerLog(description = "查询导入表") @RequestMapping("/query") public @ResponseBody Map<String, Object> findByPagination(ImportTablesPo tablesPo) { log.info("导入表查询————————"); try { int count = tableService.findCountByParms(tablesPo); List<ImportTablesWithBLOBs> list = tableService.findByPagination(tablesPo); Map<String, Object> map = new HashMap<String, Object>(); map.put("total", count); map.put("rows", list); return map; } catch (Exception e) { e.printStackTrace(); return null; } }