当前位置: 首页 > 工具软件 > Aspect C++ > 使用案例 >

如何使用@Aspect 实现AOP动态代理 --- AOP实战(二)

曾宏毅
2023-12-01

  • @Aspect则开启动态代理,结合 @Before(“xxx切入点方法”),@After(“xxx切入点方法”)等注解使用
  • @Order(xx) 是配置类的执行顺序,xx越小越先执行
  • @Pointcut("xx") 是切入点的路径位置

简洁业务代码(推荐)

@Slf4j
@Aspect
@Order(669)
@Component
public class DataIsolationAop {

    @Autowired
    private XkHttpSecurity xkHttpSecurity;


    @Pointcut("execution(* com.tzh.practice..*Controller.*(..))")
    public void pointToCut() {
    }

    @Before("pointToCut()")
    public void before(JoinPoint joinPoint) {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        获取接口名 判断是否是需要数据隔离的接口
        String servletPath = request.getServletPath();
        boolean dataIsolation = xkHttpSecurity.isDataIsolation(servletPath);

//        若是需要业务操作的接口 则将数据 放进传参内
        if (dataIsolation) {
//      校验情况
            Object[] args = joinPoint.getArgs();//获取接口参数
            if (args == null || args.length == 0) {
                return;
            }
       
//                根据不同身份(学生,学校,教育局,家长)  获取所需数据
                List<String> schoolIdList = new ArrayList<>();
                List<String> educationIdList = new ArrayList<>()
                
//-------------------------------------------    
执行相关业务代码 给予属性赋值(此处不演示)
//-------------------------------------------

            /**
             * 把所需数据 放进请求参数
             */
            for (Object arg : args) {
                if (arg instanceof PortalBasePageRequest) {//判断传参的类型,给予属性赋值
                    PortalBasePageRequest req = (PortalBasePageRequest) arg;
                    req.setEducationIdList(educationIdList);
                    req.setSchoolIdList(schoolIdList);
                } else if (arg instanceof PortalBaseRequest) {
                    PortalBaseRequest req = (PortalBaseRequest) arg;
                    req.setEducationIdList(educationIdList);
                    req.setSchoolIdList(schoolIdList);
                }
            }


        }

    }
}

详细业务代码

  • 该演示是做数据隔离的业务,在需要做数据隔离的接口中(将这些接口名放在yml下配置即可,具体操作请看获取配置文件中所有接口名),获取当前用户判断不同身份,给予不同的属性值进参数内即可, 之后即可在这些接口后续的业务逻辑中拿这些属性值做业务隔离
@Slf4j
@Aspect
@Order(669)
@Component
public class DataIsolationAop {

    @Autowired
    private XkHttpSecurity xkHttpSecurity;
    @Autowired
    private AuthUserClient authUserClient;
    @Autowired
    private BaseSchoolClient baseSchoolClient;
    @Autowired
    private BaseStudentClient baseStudentClient;
    @Autowired
    private AuthUserFamilyClient familyClient;


    @Pointcut("execution(* com.tzh.practice..*Controller.*(..))")
    public void pointToCut() {
    }

    @Before("pointToCut()")
    public void before(JoinPoint joinPoint) {

        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
//        获取接口名 判断是否是需要数据隔离的接口
        String servletPath = request.getServletPath();
        boolean dataIsolation = xkHttpSecurity.isDataIsolation(servletPath);

//        若是需要数据隔离的接口 则将数据 放进传参内
        if (dataIsolation) {
//      校验情况
            R<UserLoginResp> r = authUserClient.getBaseUser(new TokenReq(getToken(request)));
            Object[] args = joinPoint.getArgs();
            if (args == null || args.length == 0) {
                return;
            }
            UserLoginResp user = r.getEntity();
            if (Objects.isNull(user)){
                return;
            }

//                根据不同身份(学生,学校,教育局,家长)  获取所需数据
                List<String> schoolIdList = new ArrayList<>();
                List<String> educationIdList = new ArrayList<>();

                if (user.getIdentity().equals(9)){//学校身份
                    schoolIdList.add(user.getBaseId());
                    R<BaseSchoolDetailResp> schR = baseSchoolClient.getBaseSchoolById(new IdReq(user.getBaseId()));
                    BaseSchoolDetailResp sch = schR.getEntity();
                    educationIdList.add(sch.getBaseEducationId());
                }else if (user.getIdentity().equals(6)){//教育局身份
                    R<List<String>> schIdListR = baseSchoolClient.getSchoolIdListByEduId(new IdReq(user.getBaseId()));
                    if (Objects.nonNull(schIdListR.getEntity()) && schIdListR.getEntity().size() >0){
                        schoolIdList.addAll(schIdListR.getEntity());
                    }
                    educationIdList.add(user.getBaseId());
                }else if (user.getIdentity().equals(0)){//学生身份
                    R<String> schIdR =  baseStudentClient.getSchId(new IdReq(user.getBaseId()));
                    if (Objects.nonNull(schIdR.getEntity())){
                        schoolIdList.add(schIdR.getEntity());
                    }
                    R<String> eduIdR =  baseStudentClient.getEduId(new IdReq(user.getBaseId())); //通过学生baseId 找到对应的教育局id
                    if (Objects.nonNull(eduIdR.getEntity())){
                        educationIdList.add(eduIdR.getEntity());
                    }
                }else {
                    R<List<StuBindFamilyInfoResp>> familyBindStuInfo = familyClient.getNewFamilyBindStuInfo(new IdReq(user.getId()));
                    if (Objects.nonNull(familyBindStuInfo.getEntity()) && familyBindStuInfo.getEntity().size()>0){//有绑定学生信息 则是家长身份
                        List<StuBindFamilyInfoResp> familyInfoResps = familyBindStuInfo.getEntity();
                        for (StuBindFamilyInfoResp  resp: familyInfoResps){
                            R<String> eduIdR =  baseStudentClient.getEduId(new IdReq(resp.getStudentBaseId()));
                            if (Objects.nonNull(eduIdR.getEntity())){
                                educationIdList.add(eduIdR.getEntity());
                            }
                        }
                    }
                }

            /**
             * 把所需数据隔离数据 放进请求参数
             */
            for (Object arg : args) {
                if (arg instanceof PortalBasePageRequest) {
                    PortalBasePageRequest req = (PortalBasePageRequest) arg;
                    req.setEducationIdList(educationIdList);
                    req.setSchoolIdList(schoolIdList);
                } else if (arg instanceof PortalBaseRequest) {
                    PortalBaseRequest req = (PortalBaseRequest) arg;
                    req.setEducationIdList(educationIdList);
                    req.setSchoolIdList(schoolIdList);
                }
            }

        }

    }

    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(RedisConstant.TOKEN);
        if (StringUtils.isBlank(token)) {
            token = request.getParameter("token");
            if (StringUtils.isBlank(token)) {
                throw new BizException(AccountErrorEnum.NO_LOGIN);
            }
        }
        return token;
    }

}
 类似资料: