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;
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM