aop+泛型+反射 解决 若依框架分页问题 ( 实现从注解给实体类某个属性赋值)

因为项目需要,我们的数据都是与部门关联的,但是因为采用的若依框架中的分页插件在controller层使用 starePage()方法,会对第一条sql语句进行查询,我们项目需要在真正的查询表数据之前,先查询当前选择的部门,及部门下的id,所以需要将该方法放到controller层去执行,为了代码简洁,所以自定义了aop注解,上代码

首先是 泛型+反射 实现对实体类某属性赋值

 private <T>T setDeptIds(T data)throws Exception{

        /**
         * 得到类对象
         */
        Class entity = (Class) data.getClass();

        //获取指定属性
        Field field = entity.getDeclaredField("deptId");
        
        Field fields = entity.getDeclaredField("deptIds");


        field.setAccessible(true);

        fields.setAccessible(true);
        
        //获取指定属性的值
        Long deptId = (Long)(field.get(data));

        //获取部门下所有子部门
        List<Long> deptIds = ListUtils.newArrayList();

        if(deptId!=null && deptId > 0L){
            deptIds = sysDeptService.selectNormalChildrenDeptIdsByDeptId(deptId);
        }
        
        //给指定属性赋值
        fields.set(data,deptIds);

        return data;
    }
 private <T>T setDeptIds(T data)throws Exception{

        /**
         * 得到类对象
         */
        Class entity = (Class) data.getClass();

        //获取指定属性
        Field field = entity.getDeclaredField("deptId");
        
        Field fields = entity.getDeclaredField("deptIds");


        field.setAccessible(true);

        fields.setAccessible(true);
        
        //获取指定属性的值
        Long deptId = (Long)(field.get(data));

        //获取部门下所有子部门
        List<Long> deptIds = ListUtils.newArrayList();

        if(deptId!=null && deptId > 0L){
            deptIds = sysDeptService.selectNormalChildrenDeptIdsByDeptId(deptId);
        }
        
        //给指定属性赋值
        fields.set(data,deptIds);

        return data;
    }

 

然后是aop 注解 获取当前方法的参数(此处百度很久,还删掉了一些不太理解的代码才实现了)

   /**
     * 方法执行前执行
     * @param joinPoint
     */
    @Before("checkParam()")
    public <T>T doBefore(JoinPoint joinPoint)throws Exception {
        Object[] params = joinPoint.getArgs();
        if(params.length == 0){
            return null;
        }
        //获取方法,此处可将signature强转为MethodSignature
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //参数注解,1维是参数,2维是注解
        Annotation[][] annotations = method.getParameterAnnotations();
        T result = null;
        for (int i = 0; i < annotations.length; i++) {
            Object param = params[i];
            Annotation[] paramAnn = annotations[i];

            result =(T)setDeptIds(param);

            //参数为空,直接下一个参数
            if(param == null || paramAnn.length == 0){
                continue;
            }


//            for (Annotation annotation : paramAnn) {
//                //这里判断当前注解是否为Test.class
//                if(annotation.annotationType().equals(DeptDataScope.class)){
//                    //校验该参数,验证一次退出该注解
//                    //TODO 校验参数
//                    break;
//                }
//            }
        }
        return result ;

    }

接下来就是使用注解了

   /**
     * 查询备件调整单管理列表
     */
    @PreAuthorize("@ss.hasPermi('adjustDocuments:documents:list')")
    @GetMapping("/list")
    @DeptDataScope()
    public TableDataInfo list(SparePartsAdjustDocuments sparePartsAdjustDocuments) {
        startPage();
        List<SparePartsAdjustDocuments> list = sparePartsAdjustDocumentsService.selectSparePartsAdjustDocumentsList(sparePartsAdjustDocuments);
        return getDataTable(list);
    }

 

ok,至此大功告成!!! 忙了一天,虽然还有许多不足之处,但是基本需求满足了,后面慢慢优化吧。

这是aop实现类的完整代码

@Component
@Aspect
public class DeptDataScopeAop {

    @Resource
    private ISysDeptService sysDeptService;

    /**
     * 定义有一个切入点
     */
    @Pointcut("@annotation(com.*.*.aop.DeptDataScope)")
    public void checkParam() {
    }

    /**
     * 方法执行前执行
     * @param joinPoint
     */
    @Before("checkParam()")
    public <T>T doBefore(JoinPoint joinPoint)throws Exception {
        Object[] params = joinPoint.getArgs();
        if(params.length == 0){
            return null;
        }
        //获取方法,此处可将signature强转为MethodSignature
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //参数注解,1维是参数,2维是注解
        Annotation[][] annotations = method.getParameterAnnotations();
        T result = null;
        for (int i = 0; i < annotations.length; i++) {
            Object param = params[i];
            Annotation[] paramAnn = annotations[i];

            result =(T)setDeptIds(param);

            //参数为空,直接下一个参数
            if(param == null || paramAnn.length == 0){
                continue;
            }


//            for (Annotation annotation : paramAnn) {
//                //这里判断当前注解是否为Test.class
//                if(annotation.annotationType().equals(DeptDataScope.class)){
//                    //校验该参数,验证一次退出该注解
//                    //TODO 校验参数
//                    break;
//                }
//            }
        }
        return result ;

    }

    @Around(value = "(execution(public * com.nongshiyun.modules.*.*(..)))", argNames = "joinPoint")
    public <T>T doAround(ProceedingJoinPoint  joinPoint) throws Exception  {

        Object[] params = joinPoint.getArgs();
        if(params.length == 0){
            return null;
        }
        //获取方法,此处可将signature强转为MethodSignature
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        //参数注解,1维是参数,2维是注解
        Annotation[][] annotations = method.getParameterAnnotations();
        T result = null;
        for (int i = 0; i < annotations.length; i++) {
            Object param = params[i];
            Annotation[] paramAnn = annotations[i];
            //参数为空,直接下一个参数
            if(param == null || paramAnn.length == 0){
                continue;
            }
            for (Annotation annotation : paramAnn) {
                //这里判断当前注解是否为Test.class
                if(annotation.annotationType().equals(DeptDataScope.class)){
                    //校验该参数,验证一次退出该注解
                    //TODO 校验参数
                    result =(T)setDeptIds(param);
                    break;
                }
            }
        }
        return result ;
    }

    /**
     * 在切入点return内容之后切入内容(可以用来对处理返回值做一些加工处理)
     * TODO 留着做以后处理返回值用
     * @param joinPoint
     */
    @AfterReturning(value = "checkParam()", returning = "result")
    public void doAfterReturning(JoinPoint joinPoint, Object result) {

    }


    private <T>T setDeptIds(T data)throws Exception{

        /**
         * 得到类对象
         */
        Class entity = (Class) data.getClass();

        //获取指定属性
        Field field = entity.getDeclaredField("deptId");

        Field fields = entity.getDeclaredField("deptIds");


        field.setAccessible(true);

        fields.setAccessible(true);

        //获取指定属性的值
        Long deptId = (Long)(field.get(data));

        //获取部门下所有子部门
        List<Long> deptIds = ListUtils.newArrayList();

        if(deptId!=null && deptId > 0L){
            deptIds = sysDeptService.selectNormalChildrenDeptIdsByDeptId(deptId);
        }

        //给指定属性赋值
        fields.set(data,deptIds);

        return data;
    }

}

 

posted @ 2021-04-23 11:22  xdq123  阅读(1069)  评论(0编辑  收藏  举报