因为项目需要,我们的数据都是与部门关联的,但是因为采用的若依框架中的分页插件在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; } }