使用Spring的AOP进行日志记录,对应的代码为
- package cn.tiansu.eway.logAop;
- import java.lang.reflect.Method;
- import java.util.HashMap;
- import java.util.Map;
- import javax.inject.Inject;
- import org.apache.shiro.SecurityUtils;
- import org.aspectj.lang.JoinPoint;
- import org.aspectj.lang.ProceedingJoinPoint;
- import org.aspectj.lang.annotation.AfterThrowing;
- import org.aspectj.lang.annotation.Around;
- import org.aspectj.lang.annotation.Aspect;
- import org.aspectj.lang.annotation.Pointcut;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.core.Ordered;
- import org.springframework.stereotype.Component;
- import cn.tiansu.eway.annotation.SystemLog;
- import cn.tiansu.eway.entity.LogFormMap;
- import cn.tiansu.eway.mapper.LogMapper;
- import cn.tiansu.eway.util.Common;
- /**
- * 切点类
- *
- * @author LJN
- * @since 2015-05-05 Pm 20:35
- * @version 1.0
- */
- @Aspect
- @Component
- public class LogAopAction <span style="color:#ff0000;">implements Ordered</span>{
- // 本地异常日志记录对象
- private static final Logger logger = LoggerFactory.getLogger(LogAopAction.class);
- @Inject
- private LogMapper logMapper;
- // Controller层切点
- @Pointcut("@annotation(cn.tiansu.eway.annotation.SystemLog)")
- public void controllerAspect() {
- }
- /**
- * 操作异常记录
- *
- * @descript
- * @param point
- * @param e
- * @author LJN
- * @date 2015年5月5日
- * @version 1.0
- */
- @AfterThrowing(pointcut = "controllerAspect()", throwing = "e")
- public void doAfterThrowing(JoinPoint point, Throwable e) {
- LogFormMap logForm = new LogFormMap();
- Map<String, Object> map = null;
- String user = null;
- String ip = null;
- Long start = 0L;
- Long end = 0L;
- Long time = 0L;
- try {
- ip = SecurityUtils.getSubject().getSession().getHost();
- } catch (Exception ee) {
- ip = "无法获取登录用户Ip";
- }
- try {
- map = getControllerMethodDescription(point);
- // 登录名
- user = SecurityUtils.getSubject().getPrincipal().toString();
- if (Common.isEmpty(user)) {
- user = "无法获取登录用户信息!";
- }
- } catch (Exception ee) {
- user = "无法获取登录用户信息!";
- }
- try {
- start = System.currentTimeMillis();
- end = System.currentTimeMillis();
- time = end - start;
- logForm.put("accountName", user);
- logForm.put("module", map.get("module"));
- logForm.put("methods", map.get("methods"));
- logForm.put("description", "执行失败,原因:" + e);
- logForm.put("actionTime", time);
- logForm.put("userIP", ip);
- logForm.put("type", map.get("type"));
- logMapper.addEntity(logForm);
- } catch (Exception e1) {
- e1.printStackTrace();
- }
- }
- /**
- * 前置通知 用于拦截Controller层记录用户的操作
- *
- * @param joinPoint
- * 切点
- */
- @Around("controllerAspect()")
- public Object doController(ProceedingJoinPoint point) {
- Object result = null;
- // 执行方法名
- String methodName = point.getSignature().getName();
- String className = point.getTarget().getClass().getSimpleName();
- LogFormMap logForm = new LogFormMap();
- Map<String, Object> map = null;
- String user = null;
- Long start = 0L;
- Long end = 0L;
- Long time = 0L;
- String ip = null;
- try {
- ip = SecurityUtils.getSubject().getSession().getHost();
- } catch (Exception e) {
- ip = "无法获取登录用户Ip";
- }
- try {
- // 登录名
- user = SecurityUtils.getSubject().getPrincipal().toString();
- if (Common.isEmpty(user)) {
- user = "无法获取登录用户信息!";
- }
- } catch (Exception e) {
- user = "无法获取登录用户信息!";
- }
- // 当前用户
- try {
- map = getControllerMethodDescription(point);
- // 执行方法所消耗的时间
- start = System.currentTimeMillis();
- result = point.proceed();
- end = System.currentTimeMillis();
- time = end - start;
- } catch (Throwable e) {
- throw new RuntimeException(e);
- }
- try {
- logForm.put("accountName", user);
- logForm.put("module", map.get("module"));
- logForm.put("methods", map.get("methods"));
- logForm.put("type", map.get("type"));
- logForm.put("description", map.get("description"));
- logForm.put("actionTime", time.toString());
- logForm.put("userIP", ip);
- logMapper.addEntity(logForm);
- // *========控制台输出=========*//
- System.out.println("=====通知开始=====");
- System.out.println("请求方法:" + className + "." + methodName + "()");
- System.out.println("方法描述:" + map);
- System.out.println("请求IP:" + ip);
- System.out.println("=====通知结束=====");
- } catch (Exception e) {
- // 记录本地异常日志
- logger.error("====通知异常====");
- logger.error("异常信息:{}", e.getMessage());
- }
- return result;
- }
- /**
- * 获取注解中对方法的描述信息 用于Controller层注解
- *
- * @param joinPoint
- * 切点
- * @return 方法描述
- * @throws Exception
- */
- @SuppressWarnings("rawtypes")
- public Map<String, Object> getControllerMethodDescription(
- JoinPoint joinPoint) throws Exception {
- Map<String, Object> map = new HashMap<String, Object>();
- String targetName = joinPoint.getTarget().getClass().getName();
- String methodName = joinPoint.getSignature().getName();
- Object[] arguments = joinPoint.getArgs();
- Class targetClass = Class.forName(targetName);
- Method[] methods = targetClass.getMethods();
- for (Method method : methods) {
- if (method.getName().equals(methodName)) {
- Class[] clazzs = method.getParameterTypes();
- if (clazzs.length == arguments.length) {
- map.put("module", method.getAnnotation(SystemLog.class)
- .module());
- map.put("methods", method.getAnnotation(SystemLog.class)
- .methods());
- map.put("type", method.getAnnotation(SystemLog.class)
- .type());
- String de = method.getAnnotation(SystemLog.class)
- .description();
- if (Common.isEmpty(de))
- de = "执行成功!";
- map.put("description", de);
- break;
- }
- }
- }
- return map;
- }
- <span style="color:#ff0000;">@Override
- public int getOrder() {
- // TODO Auto-generated method stub
- return 1;
- }</span>
- }
Spring中的事务是通过aop来实现的,当我们自己写aop拦截的时候,会遇到跟spring的事务aop执行的先后顺序问题,比如说动态切换数据源的问题,如果事务在前,数据源切换在后,会导致数据源切换失效,所以就用到了Order(排序)这个关键字.我们可以通过在@AspectJ的方法中实现org.springframework.core.Ordered 这个接口来定义order的顺序,order 的值越小,说明越先被执行。