aop配合自定义注解玩法

package com.chinasnow.framework.interrector;/*
  类名称:UsersDataFilter
  功能描述:
  作者:
  创建时间:2021/4/14 16:07
*/

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chinasnow.framework.annotation.FilterData;
import com.chinasnow.framework.auth.jwt.JWTUtil;
import com.chinasnow.framework.protocal.DataResponse;
import com.chinasnow.framework.util.HttpSSOUtil;
import com.chinasnow.framework.util.SpringContextUtil1;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 公共切面,根据登录人过滤有效信息
 */
@Component
@Aspect
public class UsersDataFilter {



    /**
     * 切面表达式,切到各个控制层的get方法中;
     */
    @Pointcut("execution( * com.chinasnow.sal.controller.*.get(..))")
    public void getPoint() {
    }



//    /**
//     * 环绕切面,在方法执行前后进行操做;
//     * @param proceedingJoinPoint 操做元素
//     * @return
//     * @throws Throwable
//     */
//    @Around("@annotation(filterData)")
//    public Object globalAround(ProceedingJoinPoint proceedingJoinPoint, FilterData filterData) throws Throwable {
//        //获取过滤字符串
//        String filterCode = filterData.filterCode();
//        //过滤后符合条件的数据
//        List<Map> resultData=new LinkedList<>();
//        //切面切入的方法对应的参数
//     Object[] args = proceedingJoinPoint.getArgs();
//       // 由于切入的切点是list,所以第一个参数为page
//        Page argPage = (Page) args[0];
//
//        // 获取list执行后的结果
//        Object proceed =  proceedingJoinPoint.proceed();
//
//        // 将list的结果按照DataResponse进行拆分;并且格式化日期
//        Map requestDataMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
//
//        Map dataMap = JSON.parseObject(requestDataMap.get("data").toString(), Map.class);
//         // 放入过滤函数进行过滤
//        resultData = filterUserDataMap(argPage, proceedingJoinPoint, filterCode, dataMap);
//
//        // 将过滤后的数据封装到record中;
//        dataMap.put("records", resultData);
//        //将data封装到返回类型中
//        requestDataMap.put("data", dataMap);
//        DataResponse dataResponse = JSON.parseObject(JSON.toJSONString(requestDataMap), DataResponse.class);
//        return dataResponse;
//    }


    /**
     *
     * @param page 分页条件
     * @param proceedingJoinPoint 切点
     * @param filterCode 过滤字符串
     * @param paramMap  传入需要过滤的数据
     * @return
     * @throws Throwable
     */
    public List<Map> filterUserDataMap(Page page,ProceedingJoinPoint proceedingJoinPoint, String filterCode,Map paramMap) throws Throwable {
        long size = page.getSize();
        long current = page.getCurrent();
        //过滤数据集合
        List<Map> resultData=new LinkedList<>();
        boolean requestFlag=true;

        while (requestFlag){

            // 拿取到list数据
            List<Map> mapList = JSON.parseArray(paramMap.get("records").toString(), Map.class);

            // 如果过滤数据集合小于分页页码并且查询出来的数据不为空,就进行过滤并且将数据加入到过滤数据集合中
        if (resultData.size()<size&&mapList.size()>0){

                // 获取登录用户的信息
                Map<String, Object> userInfo = getUserInfoBySSO();

                // 获取登录用户的userid
                String userId = userInfo.get("name").toString();

                //获取登录用户角色
                String roles = userInfo.get("roles").toString();

                // 利用stream流对数据进行过滤:如果该数据有责任人这个选项并且登录用户不为销售管理员,则对数据进行过滤;
                // 过滤规则: 数据的责任人和登录用户相同;

                List<Map> filterData = mapList.stream().filter(map -> {
                    boolean flag = true;
                    // 如果登录用户的角色是销售管理员则给予放行;如果查看客户线索平台给予放行;
                    if (StringUtils.contains(roles, "销售管理员") || map.get("leadsSourceId") != null) {
                        return true;
                    }
                    // 如果查看的list中拥有负责人的字段并且负责人的字段为空,则过滤掉
                    if (map.get(filterCode)==null){
                        flag=false;
                    }

                    if (map.get(filterCode)!=null && !(StringUtils.contains(roles, "销售管理员"))) {
                        if ( !StringUtils.equals(map.get(filterCode).toString(), userId)) {
                            flag = false;
                        }
                    }
                    return flag;
                }).collect(Collectors.toList());
                resultData.addAll(filterData);
            }else {
                break;
            }
           //分页自增
            current++;
            Page argPage = (Page) proceedingJoinPoint.getArgs()[0];
            argPage.setCurrent(current);
            // 获取list执行后的结果
            Object proceed =  proceedingJoinPoint.proceed();

            // 将list的结果按照DataResponse进行拆分;并且格式化日期
            Map requestDataMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed, "yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
            paramMap = JSON.parseObject(requestDataMap.get("data").toString(), Map.class);
        }
            return resultData;
    }

















    /**
     * get方法公共切面,去掉mybatisplus自动填充的字段信息,解决mybatisplus修改自动填充不生效
     * @param proceedingJoinPoint
     * @return 1
     * @throws Throwable
     */
    @Around("getPoint()")
    public Object globalGetAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
        Object proceed = proceedingJoinPoint.proceed();
        Map getMap = JSON.parseObject(JSON.toJSONStringWithDateFormat(proceed,"yyyy-MM-dd HH:mm:ss", SerializerFeature.WriteDateUseDateFormat), Map.class);
        Map dataMap = JSON.parseObject(getMap.get("data").toString(), Map.class);
        dataMap.remove("assignedBy");
        dataMap.remove("assignedUserId");
        dataMap.remove("modifyBy");
        dataMap.remove("modifiedBy");
        dataMap.remove("dateModified");
        dataMap.remove("modifyDate");
        getMap.put("data",dataMap);
        DataResponse dataResponse = JSON.parseObject(JSON.toJSONString(getMap), DataResponse.class);
        return dataResponse;
    }


    /**
     * 从sso获取登录用户的信息
     *
     * @return 人员信息
     */
    private Map<String, Object> getUserInfoBySSO() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();  // 获取到http请求
        //从request请求中获取到token
        String token = request.getHeader("Cool-SSO-Token");
        //获取登录用户信息
        Map<String, Object> userInfo = HttpSSOUtil.getUserInfo(token);
        return userInfo;
    }


}

自定义注解



@Retention(RetentionPolicy.RUNTIME) //运行时作用域,会存在jvm中运行
@Target(value = {ElementType.METHOD}) // 用来描述方法
@Documented // 用来做为标识;是否生成javadoc
public @interface FilterData {
    //用来过滤的字段
    String filterCode() default "assignedUserId" ;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
AOP(面向切面编程)是一种编程范式,可以通过在不修改目标对象代码的情况下,对其进行增强或拦截,实现例如日志记录、性能统计、事务管理等功能。自定义注解是Java语言中的一种元数据,可以用于在代码中添加额外的信息,例如标记某个方法需要进行权限验证、标记某个类是单例模式等。 将AOP自定义注解搭配使用,可以更方便地实现特定功能。例如,可以使用自定义注解标记需要进行性能统计的方法,在AOP中拦截这些方法,并在方法执行前后记录方法的执行时间等信息。 具体实现步骤如下: 1. 定义自定义注解,例如: ``` @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface PerformanceLog { String value() default ""; } ``` 2. 定义AOP切面,例如: ``` @Aspect @Component public class PerformanceLogAspect { @Around("@annotation(com.example.annotations.PerformanceLog)") public Object performanceLog(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); Object result = joinPoint.proceed(); long endTime = System.currentTimeMillis(); String methodName = joinPoint.getSignature().getName(); String className = joinPoint.getTarget().getClass().getSimpleName(); String logMsg = "Method [" + className + "." + methodName + "] took " + (endTime - startTime) + " ms."; System.out.println(logMsg); return result; } } ``` 3. 在目标方法上添加自定义注解,例如: ``` @Service public class UserService { @PerformanceLog("getUserById") public User getUserById(Long id) { //... } } ``` 这样,在调用getUserById方法时,AOP会拦截该方法,并输出方法的执行时间等信息。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值