首先在maven项目中添加spring 切面的包在pom文件中添加pom依赖
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.3.12.RELEASE</version>
</dependency>
然后再spring-mvc配置文件中的xsi:schemaLocation新增
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
将自己的切面类注入spring容器
<bean id="systemLogAspect" class="com.demo.annotation.SystemLogAspect"/>
新增开启注解的配置和
CGLIB代理
<mvc:annotation-driven />
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
然后定义自己的切面类
其中controllerAspect为基于注解方式的切面拦截 exceptionAspect() 为基于包的切面拦截 @After为后置通知,也就是说在方法执行完成之后才进行切面拦截,@AfterThrowing为抛出异常之后进行切面拦截,下面是对一些注解的详细描述@Aspect @Component public class SystemLogAspect { // Controller层切点 @Pointcut("@annotation(com.demo.annotation.SystemControllerLog)") public void controllerAspect() { } @Pointcut("execution(* com.demo.controller..*.*(..))") public void exceptionAspect() { } @After("controllerAspect()") public void doAfter(JoinPoint joinPoint) { Object[] methodParams = joinPoint.getArgs(); HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); HttpSession session = request.getSession(); // 读取session中的用户 Users user = (Users) session.getAttribute("user"); try { SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String time = sdf.format(new Date()); InetAddress addr = InetAddress.getLocalHost(); //获得本机IP String ip=addr.getHostAddress(); ArrayList result=getControllerMethodDescription(joinPoint); int operateType=(int) result.get(1); String description=(String) result.get(0); int state=logService.insertLog(user.getDepartmentId(), operateType, user.getUserName(), user.getRealName(), description); System.out.println("=====后置通知结束====="); } catch (Exception e) { // 记录本地异常日志 logger.error("==后置通知异常=="); logger.error("异常信息:{}", e.getMessage()); } } @AfterThrowing(pointcut = "exceptionAspect()", throwing = "e") public void doAfterThrowing(JoinPoint joinPoint,Throwable e) throws UnknownHostException { HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()) .getRequest(); HttpSession session = request.getSession(); Users user = (Users) session.getAttribute("user"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss"); String time = sdf.format(new Date()); InetAddress addr = InetAddress.getLocalHost(); String ip=addr.getHostAddress(); String params = ""; if (joinPoint.getArgs() != null && joinPoint.getArgs().length > 0) { for (int i = 0; i < joinPoint.getArgs().length; i++) { params += JSON.toJSONString(joinPoint.getArgs()[i]) + ";"; } } try { System.out.println("=====异常通知开始====="); System.out.println("异常代码:" + e.getClass().getName()); System.out.println("异常信息:" + e.getMessage()); System.out.println("异常方法:"+ (joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); System.out.println("请求人:" + user.getRealName()); System.out.println("请求IP:" + ip); System.out.println("请求参数:" + params); // 保存数据库 System.out.println("=====异常通知结束====="); SystemException systemException=new SystemException(); systemException.setExceptionCode(e.getClass().getName()); systemException.setExceptionFunction((joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + "()")); systemException.setExceptionMessage(e.getMessage()); systemException.setIp(ip); systemException.setUserId(user.getId()); systemException.setUserRealName(user.getRealName()); systemException.setParams(params); logService.insertSysException(systemException); } catch (Exception ex) { // 记录本地异常日志 logger.error("==异常通知异常=="); logger.error("异常信息:{}", ex.getMessage()); } }
}/** * 获取注解中对方法的描述信息 用于Controller层注解 * * @param joinPoint 切点 * @return 方法描述 * @throws Exception */ @SuppressWarnings("unchecked") public static ArrayList 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); Method[] methods = targetClass.getMethods(); ArrayList result=new ArrayList<>(); String description = ""; int operatorType=0; for (Method method : methods) { if (method.getName().equals(methodName)) { Class[] clazzs = method.getParameterTypes(); if (clazzs.length == arguments.length) { Annotation aaa=method.getAnnotation(SystemControllerLog.class); description = method.getAnnotation(SystemControllerLog.class).description(); operatorType= method.getAnnotation(SystemControllerLog.class).operateType(); result.add(description); result.add(operatorType); break; } } } return result; }
getControllerMethodDescription 方法是根据切点获取方法上面注解的参数
自定义SystemControllerLog注解
/**
* 自定义注解 拦截Controller
*/
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SystemControllerLog {
/** 要执行的具体操作比如:用户登录 **/
public String description() ;
public int operateType();
}
然后是使用
SystemControllerLog注解
/**
*
* @param session
* @param request
* @param response
* @throws IOException
*/
@RequestMapping(value = "/inApproveBrief", method = RequestMethod.POST)
@SystemControllerLog(description = operat.S_INNER_BORROW_PROCESS, operateType =operat.INNER_BORROW_PROCESS)
public void inApproveBrief(HttpSession session, HttpServletRequest request, HttpServletResponse response)
throws IOException {
}