Spring AOP应用 权限管理实现

发布于 2021-07-06  973 次阅读


参考:https://blog.csdn.net/u013310119/article/details/105270552/
https://www.cnblogs.com/huangzhe1515023110/p/9276055.html

1.Aop实现权限控制(切入点为被指定注解)
    1.1 添加aop相关Maven依赖
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.9.6</version>
</dependency>

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>${spring.version}</version>
</dependency>
    1.2 修改Spring配置,添加下列代码。
<aop:aspectj-autoproxy />声明自动为spring容器中那些配置@aspectJ切面的bean创建代 理。有一个proxy-target-class属性,默认为false,表示使用jdk动态代理织入增强,当配为<aop:aspectj-autoproxy  poxy-target-class="true"/>时,表示使用CGLib动态代理技术织入增强。不过即使proxy-target-class设置为false,如果目标类没有声明接口,则spring将自动使用CGLib动态代理。
 <aop:aspectj-autoproxy proxy-target-class="false"/>
1.3修改SpringMVC配置
1.3.1在beans标签里面引入aop标签支持
xmlns:aop="http://www.springframework.org/schema/aop"

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
1.3.2 添加配置。同spring配置一样(猜测controller和Service的aop要分开配置,未证实)
 <aop:aspectj-autoproxy proxy-target-class="false"/>
1.4 新建注解接口(切入点)
package org.book.aop;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PermissionCheck {

}
说明:
    @Documented注解表明这个注解要被javadoc记录。注解默认状态下是不被javadoc记录的。
    @Retention注解表明该注解保留到那个阶段,主要有三个值:
        SOURCE —— 这种注解保留在源代码级别,编译时就会被忽略
        CLASS —— 这种注解编译时被保留,在class文件中存在,但JVM将会忽略
        RUNTIME —— 这种注解将被JVM保留,利用反射机制可以获取并使用。
    @Target注解表明该注解作用的范围。包括package、method、field、构造方法、成员变量、枚举值等属性。
    @Inherited注解表明该注解是否影响子类。如果定义的注解上使用了@Inherited标记,则使用该注解的某个父类,它的子类默认继承所有的属性
1.5新建切面类 详情看注解
package org.book.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.book.bean.Manager;
import org.book.common.JsonResult;
import org.book.service.IManagerService;
import org.book.utils.SysContent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;


@Aspect//声明本类是切面
@Component//声明组件
@Slf4j
public class PermissionCheckAspect {
    @Autowired
    IManagerService managerService;

    @Pointcut("@annotation(org.book.aop.PermissionCheck)")//拦截被PermissionCheck注解的方法
    private void scall(){}
    /**
     * 环绕
     */
    @Around("scall()")
    public Object prepareFood(ProceedingJoinPoint joinPoint) throws Throwable{
        log.info("进入切面方法");
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();          //从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = (HttpServletRequest) requestAttributes.resolveReference(RequestAttributes.REFERENCE_REQUEST);
        HttpSession session= request.getSession();//获取session
        String name = ""+session.getAttribute("user");//获取登录的信息
        Manager manager =null;
        try {
            manager = managerService.getById(name);
        }catch (Exception e){
            return JsonResult.renderFail("你没有权限");
        }
        if(manager==null||manager.getUsername()==null||manager.getUsername().equals("")){
            return JsonResult.renderFail("你没有权限");
        }
        return joinPoint.proceed();
    }

}
1.6 在需要切入的方法前添加注解(即之前新建的注解 PermissionCheck), 
1.7 前置通知、后置通知等
未完待续。。。。。