因為項目需要,我們的數據都是與部門關聯的,但是因為采用的若依框架中的分頁插件在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; } }