AOP类分析

目录

代码

controller层

service层Impl

mapper.xml

AOP

DataScope注解内部

 DataScope对应的切面类

doBefore函数 

clearDataScope

handleDtaScope

dataScopeFilter

  总结


代码

controller层

 @PreAuthorize("@ss.hasPermi('system:myworkshop:list')")
    @GetMapping("/list")
    public TableDataInfo list(Myworkshop myworkshop)
    {
        startPage();
        List<Myworkshop> list = myworkshopService.selectMyworkshopList(myworkshop);
        return getDataTable(list);
    }

controller层调用service层的selsectMyworkshopList函数

service层Impl

 @Override
    @DataScope(deptAlias = "d",userAlias = "u")
    public List<Myworkshop> selectMyworkshopList(Myworkshop myworkshop)
    {
        return myworkshopMapper.selectMyworkshopList(myworkshop);
    }

 使用DataScope注解,deptAlias为部门表别称,userAlias为用户表别称

返回给controller对应用户的数据

mapper.xml

select l.id, l.name, l.temp, l.dept_id from myworkshop l left join sys_dept d on l.dept_id=d.dept_id where l.id is not null

将l和sys_sept d相连, 条件为两表dept_id相等,且l中的 id值不为空。

datascope传参${params.dataScope}

AOP

DataScope注解内部

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DataScope
{
    /**
     * 部门表的别名
     */
    public String deptAlias() default "";

    /**
     * 用户表的别名
     */
    public String userAlias() default "";
}

 DataScope对应的切面类

@Aspect
@Component
public class DataScopeAspect

切面类中的方法 

doBefore函数 

@Before("@annotation(controllerDataScope)")
    public void doBefore(JoinPoint point, DataScope controllerDataScope) throws Throwable
    {
        clearDataScope(point);
        handleDataScope(point, controllerDataScope);
    }

Before:监听注解,类型为controllerDataScope 对应的注解类型@DataScope  

监听到有使用DdataScope注解的函数时,首先执行doBefore函数

clearDataScope

/**
     * 拼接权限sql前先清空params.dataScope参数防止注入
     */
    private void clearDataScope(final JoinPoint joinPoint)
    {
        Object params = joinPoint.getArgs()[0];
        if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
        {
            BaseEntity baseEntity = (BaseEntity) params;
            baseEntity.getParams().put(DATA_SCOPE, "");
        }
    }
}

首先joinPoint.getArgs()[0]获取参数,判断传入参数是否为BaseEtity子类防止注入,然后进行权限SQL拼接。

handleDtaScope

protected void handleDataScope(final JoinPoint joinPoint, DataScope controllerDataScope)
    {
        // 获取当前的用户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        if (StringUtils.isNotNull(loginUser))
        {
            SysUser currentUser = loginUser.getUser();
            // 如果是超级管理员,则不过滤数据
            if (StringUtils.isNotNull(currentUser) && !currentUser.isAdmin())
            {
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.deptAlias(),
                        controllerDataScope.userAlias());
            }
        }
    }

获取当前用户,判断是否过滤数据。 

dataScopeFilter

/**
     * 数据范围过滤
     *
     * @param joinPoint 切点
     * @param user 用户
     * @param userAlias 别名
     */
    public static void dataScopeFilter(JoinPoint joinPoint, SysUser user, String deptAlias, String userAlias)
    {
        StringBuilder sqlString = new StringBuilder();

        for (SysRole role : user.getRoles())
        {
            。。。。。。
            else if (DATA_SCOPE_DEPT.equals(dataScope))
            {
                sqlString.append(StringUtils.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
            }
            。。。。。。。
        if (StringUtils.isNotBlank(sqlString.toString()))
        {
            Object params = joinPoint.getArgs()[0];
            if (StringUtils.isNotNull(params) && params instanceof BaseEntity)
            {
                BaseEntity baseEntity = (BaseEntity) params;
                baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
            }
        }
    }

 在循环中判断在用户权限管理中选择了哪一个选项,是否为“只显示本部门数据”

 在SQL中插入的语句为OR d.dept_id=201

下一个if语句将OR转换为AND

AND (d.dept_id = 105)这个语句被传回给${params.datascope}

  总结

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值