这篇文要做一件事,当请求来时,每次都要管分页,很烦。 所以使用打算用AOP, Mybatis PageHelper和反射机制写一个识别请求的API是否是返回列表的。如果是,获取page, size, 进行分页。
实现结果
传入参数 实现自动分页回顾AOP
AOP图解实现流程
切面
package com.accat.springmvc.SourceDemo.aspects;
import com.github.pagehelper.PageHelper;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.CollectionUtils;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
/*
* @program springmvc.SourceDemo
* @description
* @author Rudolph Browne
* @create 19-1-22
*/
@Aspect
@Configuration
@PropertySource("classpath:application.properties")
public class PaginationAspect {
@Value("${mybatis.pagehelper.page}")
private int page;
@Value("${mybatis.pagehelper.size}")
private int size;
@Pointcut("@annotation(com.accat.springmvc.SourceDemo.annotation.Paginate)")
public void paginate1(){}
@Pointcut("execution(* com.accat.springmvc.SourceDemo.service.impl.DemoServiceImpl.*(..))")
public void paginate2(){}
//@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
@Before("paginate1() || paginate2()")
public void startPage(JoinPoint joinPoint) {
Method currentMethod = ((MethodSignature)joinPoint.getSignature()).getMethod();
// 1.获取到当前方法的方法签名, 判断返回类型是否是List, 如果是则执行分页逻辑
boolean isPaginate = currentMethod.getReturnType().equals(List.class);
if (isPaginate) {
// 2.获取参数page, size, 或者访问application.properties, 读取分页默认参数
Arrays.stream(joinPoint.getArgs()).forEach(parameter -> {
if (parameter instanceof Map) {
Map parameter0 = (Map)parameter;
if (parameter0.containsKey("page") && parameter0.containsKey("size")) {
this.page = Integer.valueOf((String) parameter0.get("page"));
this.size = Integer.valueOf((String) parameter0.get("size"));
}
}
});
// 3.输出page, size,
// PageHelper.startPage(page, size);
System.out.println("方法签名: " + joinPoint.getSignature());
System.out.println("参数列表: " + Arrays.asList(joinPoint.getArgs()));
PageHelper.startPage(page, size);
}
}
}
被切的类
package com.accat.springmvc.SourceDemo.service.impl;
import com.accat.springmvc.SourceDemo.annotation.Paginate;
import com.accat.springmvc.SourceDemo.dao.DemoDao;
import com.accat.springmvc.SourceDemo.model.Demo;
import com.accat.springmvc.SourceDemo.model.DemoModel;
import com.accat.springmvc.SourceDemo.service.DemoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Map;
/*
* @program springmvc.SourceDemo
* @description
* @author Rudolph Browne
* @create 19-1-19
*/
@Service("demoServiceImpl")
public class DemoServiceImpl implements DemoService {
@Autowired
private DemoDao demoDao
@Override
@Paginate
public List<DemoModel> handleTransactionAndListDemo(Map<String, String> parameterMap) {
// 处理逻辑
return demoDao.listDemosFromCacheOrDB(parameterMap);
}
}
application.properties
mybatis.pagehelper.page=1
mybatis.pagehelper.size=2
启动类注意:需要将切面, 切面类和被切类必须放置在同一个上下文环境中(ApplicationContext),
这里都标记@Service和@Configuration将由SpringBoot启动类统一扫描后进行Ioc Bean管理。
网友评论