1. 程式人生 > >Spring 的 AOP切面用法

Spring 的 AOP切面用法


 * 攔截器:記錄使用者操作日誌,檢查使用者是否登入……

@Aspect
@Component

public class ControllerInterceptor {
    private static final Logger logger = LoggerFactory.getLogger(ControllerInterceptor.class);

    @Value("${spring.profiles}")
    private String env;

    @Autowired
    private SystemLogsService systemLogsService;

    /**
     * 定義攔截規則:攔截com.space.web.controller包下面的所有類中,有@RequestMapping註解的方法。
     */

    @Pointcut("execution(* com.space.web.controller..*(..)) and @annotation(org.springframework.web.bind.annotation.RequestMapping)")
    public void controllerMethodPointcut()

{

    }

    /**
     * 攔截器具體實現
     * 
     * @param pjp
     * @return JsonResult(被攔截方法的執行結果,或需要登入的錯誤提示。)
     */

    @Around("controllerMethodPointcut()")
    // 指定攔截器規則;也可以直接把“execution(* com.space.........)”寫進這裡


    public Object Interceptor(ProceedingJoinPoint pjp) {
        long beginTime = System.currentTimeMillis();
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod(); // 獲取被攔截的方法
        String methodName = method.getName(); // 獲取被攔截的方法名

        Set<Object> allParams = new LinkedHashSet<>(); // 儲存所有請求引數,用於輸出到日誌中

        String userid = "";
        String referer = "";
        String starttime = XDateUtils.nowToString();
        logger.info("請求開始,方法:{}", methodName);

        Object result = null;

        Object[] args = pjp.getArgs();
        for (Object arg : args) {
            // logger.debug("arg: {}", arg);
            if (arg instanceof Map<?, ?>) {
                // 提取方法中的MAP引數,用於記錄進日誌中
                @SuppressWarnings("unchecked")
                Map<String, Object> map = (Map<String, Object>) arg;

                allParams.add(map);
            } else if (arg instanceof HttpServletRequest) {
                HttpServletRequest request = (HttpServletRequest) arg;
                try {
                    HttpSession session = request.getSession();
                    if (!(session == null ? "" : session).equals("")) {
                        Object userCode = session.getAttribute("usercode");
                        if (!(userCode == null ? "" : userCode).equals("")) {
                            userid = userCode.toString();
                        }
                    }

                    referer = request.getHeader("Referer"); // 來源
                    if ((referer == null || referer.isEmpty() ? "" : referer).equals("")) {
                        referer = HttpVisitors.ip(request);
                    }

                    URL rUrl = new URL(request.getRequestURL().toString());
                    String domain = rUrl.getHost().toLowerCase();
                    String port = ":" + String.valueOf(rUrl.getPort());
                    if (rUrl.getPort() == 80) {
                        port = "";
                    }
                    String basicUrl = request.getScheme() + "://" + domain + port + request.getContextPath();

                    GlobalConfig.setScheme(request.getScheme());
                    GlobalConfig.setDomain(domain);
                    GlobalConfig.setPort(rUrl.getPort());
                    GlobalConfig.setContextPath(request.getContextPath());
                    GlobalConfig.setBasicUrl(basicUrl);

                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                }
                if (isLoginRequired(method)) {
                    if (!isLogin(request)) {
                        result = new JsonResult(ResultCode.NOT_LOGIN, "該操作需要登入!");
                    }
                }

                // 獲取query string 或 posted form data引數
                Map<String, String[]> paramMap = request.getParameterMap();
                if (paramMap != null && paramMap.size() > 0) {
                    allParams.add(paramMap);
                }
            } else if (arg instanceof HttpServletResponse) {
                // do nothing...
            } else {
                // allParams.add(arg);
            }
        }

        String abnormalinfor = "";
        try {
            if (result == null) {
                // 一切正常的情況下,繼續執行被攔截的方法
                result = pjp.proceed();
            }
        } catch (Throwable e) {
            logger.info("exception: ", e);
            abnormalinfor = e.getMessage();
            result = new JsonResult(ResultCode.EXCEPTION, "發生異常:" + e.getMessage());
        }

        if (result instanceof JsonResult) {
            long costMs = System.currentTimeMillis() - beginTime;
            logger.info("{}請求結束,耗時:{}ms", methodName, costMs);

            try {
                SystemLogs log = new SystemLogs();
                log.setUserid(userid);
                log.setMethod(methodName);
                log.setStarttime(starttime);
                log.setEndtime(XDateUtils.nowToString());
                log.setConsumtime(costMs);
                log.setAbnormalinfor(abnormalinfor);
                log.setReferer(referer);
                systemLogsService.insertSystemLog(log);
            } catch (Exception e) {
            }
        }

        return result;
    }

    /**
     * 判斷一個方法是否需要登入
     * 
     * @param method
     * @return
     */
    private boolean isLoginRequired(Method method) {
        // 只有生產環境才需要登入
        if (!env.equals("prd")) {
            return false;
        }
        boolean result = true;
        if (method.isAnnotationPresent(Permission.class)) {
            result = method.getAnnotation(Permission.class).loginReqired();
        }
        return result;
    }

    /***
     * 判斷是否已經登入
     * 
     * @param request
     * @return
     */
    private boolean isLogin(HttpServletRequest request) {
        HttpSession session = request.getSession();
        if (!(session == null ? "" : session).equals("")) {
            Object userID = session.getAttribute("usercode");
            if (!(userID == null ? "" : userID).equals("")) {
                return true;
            }
        }
        return false;
    }
}