zoukankan      html  css  js  c++  java
  • AOP

    package com.foen.foensys.config;

    import com.alibaba.fastjson.JSON;
    import com.foen.foensys.model.SysLogsOper;
    import com.foen.foensys.model.Users;
    import com.foen.foensys.service.SysLogsOperService;
    import com.foen.foensys.controller.admin.BaseController;
    import com.foen.foensys.utils.DateUtils;
    import com.foen.foensys.utils.Utils;
    import com.google.common.collect.Maps;
    import org.apache.shiro.SecurityUtils;
    import org.aspectj.lang.JoinPoint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.Signature;
    import org.aspectj.lang.annotation.*;
    import org.aspectj.lang.reflect.MethodSignature;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springframework.web.context.request.RequestAttributes;
    import org.springframework.web.context.request.RequestContextHolder;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpSession;
    import java.lang.reflect.Method;
    import java.util.Date;
    import java.util.Enumeration;
    import java.util.Map;


    /**
    * AOP
    * @auther: 作者 gzh
    * @description: 类说明
    * @Date: created in 15:33 2019/7/5
    */
    @Order(value=1)//多个切面 ,第一个切面,
    @Component
    @Aspect
    public class SystemLogsOperAopAction {

    private static final Logger logger = LoggerFactory.getLogger(SystemLogsOperAopAction.class);

    @Autowired
    private SysLogsOperService sysLogsOperService;

    /**
    * 00配置接入点:定义一个切入点
    * execution(* com.foen.foensys.controller..*.*(..))") "*" 第一个* 任何返回值
    */
    //@Pointcut("execution(* com.foen.foensys.controller..*.*(..))")
    //@Pointcut("execution(* com.foen.foensys.controller.admin..*.*(..))")//这个包子包类的所有方面
    //@Pointcut("execution(* com.foen.foensys.controller.admin.*.*(..))")//这个包下的所有类
    //@Pointcut("execution(* com.foen.foensys.controller.admin.LoginController.*(..))")//这个类的所有方法
    //@Pointcut("execution(* com.foen.foensys.controller.admin.MenuController.*(..))")//这个类的所有方法
    @Pointcut("execution(@com.foen.foensys.config.SystemLogs * *(..))")
    private void controllerAspect(){
    logger.info("==》 Controller Log记录!");
    }

    /**
    * 环绕通知(之前前置,之后,后置通知,最终通知,整个生命周期都包括了)
    * @param proceedingJoinPoint
    * @return Object
    * @throws Throwable

    @Around("controllerAspect()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    //常见日志实体对象
    logger.info("==>环绕通知的目标方法名为 : "+proceedingJoinPoint.getSignature().getName());

    SysLogsOper log = new SysLogsOper();
    //获取登录用户账户
    //HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    //String name = (String)request.getSession().getAttribute("userID");

    Users user = (Users) SecurityUtils.getSubject().getSession().getAttribute("user");
    if(user!=null){
    log.setUserId(user.getId().toString());
    log.setUserName(user.getUsername());
    }
    log.setOperTime(DateUtils.dateToStringDetail(new Date()));
    log.setIp(Utils.getLocalIP());
    log.setPort(Utils.getLocalPort());
    log.setPath("/**");
    log.setParam("{**}");

    //方法通知前获取时间,为什么要记录这个时间呢?当然是用来计算模块执行时间的
    long start = System.currentTimeMillis();
    // 拦截的实体类,就是当前正在执行的controller
    Object target = proceedingJoinPoint.getTarget();
    // 拦截的方法名称。当前正在执行的方法
    String methodName = proceedingJoinPoint.getSignature().getName();
    // 拦截的方法参数
    Object[] args = proceedingJoinPoint.getArgs();
    // 拦截的放参数类型
    Signature sig = proceedingJoinPoint.getSignature();
    MethodSignature msig = null;
    if (!(sig instanceof MethodSignature)) {
    throw new IllegalArgumentException("该注解只能用于方法");
    }
    msig = (MethodSignature) sig;
    Class[] parameterTypes = msig.getMethod().getParameterTypes();

    Object object = null;
    // 获得被拦截的方法
    Method method = null;
    try {
    method = target.getClass().getMethod(methodName, parameterTypes);
    } catch (NoSuchMethodException e1) {
    e1.printStackTrace();
    } catch (SecurityException e1) {
    e1.printStackTrace();
    }
    if (null != method) {
    // 判断是否包含自定义的注解,说明一下这里的SystemLog就是我自己自定义的注解
    if (method.isAnnotationPresent(SystemLogs.class)) {
    logger.info("==>判断是否包含自定义的注解:包含注解!");
    SystemLogs systemlog = method.getAnnotation(SystemLogs.class);
    log.setModule(systemlog.module());
    log.setMethod(systemlog.methods());
    long end = System.currentTimeMillis();
    log.setResponseTime(""+(end-start));
    try {
    object = proceedingJoinPoint.proceed();
    log.setRemark("执行成功!");
    sysLogsOperService.save(log);
    } catch (Throwable e) {
    log.setRemark("执行失败");
    sysLogsOperService.save(log);
    }
    } else {
    logger.info("==>没有包含注解");
    object = proceedingJoinPoint.proceed();
    log.setModule("");
    log.setMethod("");
    log.setResponseTime("0");
    log.setRemark("执行成功!");
    sysLogsOperService.save(log);
    }
    } else {
    logger.info("==>不需要拦截直接执行");
    object = proceedingJoinPoint.proceed();
    }
    logger.info("==> 退出 环绕通知! object:"+object);
    return object;
    }*/

    /**
    * 前置
    * 1. 通过JoinPoint 获取通知的签名信息,如目标方法名,目标方法参数信息等
    * @param joinPoint
    */
    @Before(value = "controllerAspect()")
    public void doAccessCheck(JoinPoint joinPoint){
    logger.info("==>:前置通知");
    Object[] obj=joinPoint.getArgs();//获取目标方法的参数信息
    joinPoint.getThis(); // AOP代理类信息
    joinPoint.getTarget(); // 代理的目标对象
    Signature signature=joinPoint.getSignature(); // 用的最多,通知的签名
    logger.info("代理的方法是 : "+signature.getName()); // 打印 代理的是哪一个方法
    // AOP 代理的名字
    logger.info("AOP 代理的名字 : "+signature.getDeclaringTypeName());
    signature.getDeclaringType();// AOP代理类的类(class)信息
    // 获取RequestAttributes
    RequestAttributes requestAttributes= RequestContextHolder.getRequestAttributes();
    // 从requestAttributes中获取HttpServletRequest信息
    HttpServletRequest request=(HttpServletRequest)requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
    // 获取session信息
    HttpSession session=(HttpSession)requestAttributes.resolveReference(RequestAttributes.REFERENCE_SESSION);

    logger.info("请求 : "+request+" , HttpSession : "+session);
    Enumeration<String> enumerations=request.getParameterNames();
    Map<String,Object> parameterMaps= Maps.newHashMap();
    while(enumerations.hasMoreElements()){
    String parameter=enumerations.nextElement();
    parameterMaps.put(parameter,request.getParameter(parameter));
    }

    logger.info("请求参数信息为 : "+ JSON.toJSONString(parameterMaps) );
    // this.map = parameterMaps;
    // this.request = request;
    SysLogsOper log = new SysLogsOper();
    log.setOperTime(DateUtils.dateToStringDetail(new Date()));
    log.setUserId("11");
    log.setUserName("111111111");
    log.setIp(Utils.getLocalIP());
    log.setPort("");
    log.setPath("/**");
    log.setParam("{**}");
    log.setModule("");
    log.setMethod("");
    log.setResponseTime("0");
    log.setRemark("执行成功!");
    sysLogsOperService.save(log);
    }

    /**
    * 后置通知
    * @param joinPoint
    * @param keys 返回值的信息

    @AfterReturning(value = "controllerAspect()",returning = "keys")
    public void doAfter(JoinPoint joinPoint,Object keys){
    logger.info("==>:后置通知:keys:"+keys+",joinPoint:"+joinPoint);
    }
    */
    /**
    * 04. 后置最终通知(目标方法只要执行完了就会执行后置通知方法)

    @After("controllerAspect()")
    public void after(JoinPoint joinPoint){
    logger.info("==>:最终通知:"+joinPoint);
    } */

    /**
    * 03 . 后置异常通知
    * 定义一个名字,该名字用于匹配通知实现方法的一个参数名,当目标方法抛出异常返回后,将把目标方法抛出的异常传给通知方法;
    * throwing 限定了只有目标方法抛出的异常与通知方法相应参数异常类型时才能执行后置异常通知,否则不执行,
    * 对于throwing对应的通知方法参数为Throwable类型将匹配任何异常。

    @AfterThrowing(value = "controllerAspect()" ,throwing = "exception")
    public void doAfterThrow(JoinPoint joinPoint,Throwable exception){
    logger.error("目标方法名[后置异常]:"+joinPoint.getSignature().getName());
    if(exception instanceof NullPointerException){
    logger.error("发生了空指针异常");
    }
    }*/

    }
  • 相关阅读:
    Java 简单算法--打印乘法口诀(只使用一次循环)
    Java简单算法--求100以内素数
    ubuntu 16.04 chrome flash player 过期
    java 网络API访问 web 站点
    java scoket (UDP通信模型)简易聊天室
    leetcode1105 Filling Bookcase Shelves
    leetcode1140 Stone Game II
    leetcode1186 Maximum Subarray Sum with One Deletion
    leetcode31 Next Permutation
    leetcode834 Sum of Distances in Tree
  • 原文地址:https://www.cnblogs.com/gzhbk/p/11812947.html
Copyright © 2011-2022 走看看