Spring AOP 实现PageHelper自动分页

2019-01-24  本文已影响0人  阿武_Accat

这篇文要做一件事,当请求来时,每次都要管分页,很烦。 所以使用打算用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管理。

启动类
上一篇下一篇

猜你喜欢

热点阅读