本文主要是介绍如何使用@Aspect 实现AOP动态代理 --- AOP实战(二),对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
@Aspect
则开启动态代理,结合 @Before(“xxx切入点方法”),@After(“xxx切入点方法”)等注解使用@Order(xx)
是配置类的执行顺序,xx越小越先执行@Pointcut("xx")
是切入点的路径位置
简洁业务代码(推荐)
- 这里注入的
XkHttpSecurity
请转至@ConfigurationProperties用法 了解
@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;
}
}
这篇关于如何使用@Aspect 实现AOP动态代理 --- AOP实战(二)的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!