使用springAOP实现权限控制

使用springAOP实现权限控制

说明:

  • 这里使用的配置方式是:注解+xml文件的方式
  • 三个角色:的权限设置
    1. const:只能注册
    2. user:注册+查询+修改
    3. admin:注册+查询+修改+删除

1、搭建基本环境

  1. 导入依赖

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
            <scope>compile</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.11</version>
        </dependency>
        <!-- spring-aspects会帮我们传递过来aspectjweaver -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>5.3.1</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.29</version>
        </dependency>
    </dependencies>
    
  2. 实体类User

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
    
        private int id;
    
        private String username;
    
        private String address;
    
    
    }
    
  3. controller层添加UserController的注解,

    @Controller
    public class UserController {
    
        @Autowired
        private UserService userService;
    
        public void registUser(User user){
            userService.registUser(user);
        }
    
        public void updateUser(User user){
            userService.updateUser(user);
        }
    
        public void deleteUserById(int id){
            userService.deleteUserById(id);
        }
    
        public User queryUserById(int id){
            return userService.queryUserById(id);
        }
    }
    
    
  4. service层添加UserService与实现类

    public interface UserService {
        void registUser(User user);
        void updateUser(User user);
        void deleteUserById(int id);
        User queryUserById(int id);
    }
    
    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
        @Override
        public void registUser(User user) {
            userDao.registUser(user);
        }
    
        @Override
        public void updateUser(User user) {
            userDao.updateUser(user);
        }
    
        @Override
        public void deleteUserById(int id) {
            userDao.deleteUserById(id);
        }
    
        @Override
        public User queryUserById(int id) {
            return userDao.queryUserById(id);
        }
    }
    
    
  5. dao层添加UserDao接口与UserDaoImpl实现类

    public interface UserDao {
        void registUser(User user);
    
        void updateUser(User user);
    
        void deleteUserById(int id);
    
        User queryUserById(int id);
    }
    
    
    @Repository
    public class UserDaoImpl implements UserDao {
        @Override
        public void registUser(User user) {
            System.out.println("注册用户成功" + user);
        }
    
        @Override
        public void updateUser(User user) {
            System.out.println("更新用户成功" + user);
        }
    
        @Override
        public void deleteUserById(int id) {
            System.out.println("删除用户成功" + id);
        }
    
        @Override
        public User queryUserById(int id) {
            if (id == 1)
                return new User(1,"孙悟空","花果山");
            return null;
        }
    }
    
  6. 添加applicationContext.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--开启包扫描-->
        <context:component-scan base-package="cn.javasm"></context:component-scan>
    </beans>
    
  7. 加载配置类,注册IOC容器

    public class TestDemo {
        // cust  user  admin
        public static String role = "admin";
        public static void main(String[] args) {
    
            // 加载核心配置文件
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取对象
            UserController userController = applicationContext.getBean(UserController.class);
            User user = new User(2, "猪八戒", "高老庄");
            userController.registUser(user);
            userController.updateUser(user);
            System.out.println(userController.queryUserById(1));
            userController.deleteUserById(2);
        }
    }
    
  8. 测试成功

2、思路说明:

使用自定义注解在service层中的实现方法上标记用户,如果一个方法上拥有该用户的名字则拥有该权限

准备工作:

  1. 创建一个自定义注解 目的:为了做标记
  2. 创建一个枚举类存放这三个用户 目的:为了后期扩展,方便维护
  3. 创建切面类 目的:使用spring的AOP框架来简化动态代理技术

3、创建工作

  1. 创建枚举类,定义三个用户权限

    public enum PrivEnum {
        CUST,USER,ADMIN;
    }
    
    
  2. 自定义枚举

    @Target(ElementType.METHOD) //作用范围为方法
    @Retention(RetentionPolicy.RUNTIME)  //运行时,起作用
    public @interface PrivAnnotation {
        PrivEnum [] value() default PrivEnum.CUST; //使用枚举来
    }
    
  3. 在servic层中给操作方法添加注解作为标记

    注意:对于注册方法registUser都有该权限,我们可以使用不做标记的方式作为判断,在切面类内放行

    @Service
    public class UserServiceImpl implements UserService {
        @Autowired
        private UserDao userDao;
        @Override
        public void registUser(User user) {
            userDao.registUser(user);
        }
    
        @Override
        @PrivAnnotation(value = {PrivEnum.USER,PrivEnum.ADMIN})
        public void updateUser(User user) {
            userDao.updateUser(user);
        }
    
        @Override
        @PrivAnnotation(value = {PrivEnum.ADMIN})
        public void deleteUserById(int id) {
            userDao.deleteUserById(id);
        }
    
        @Override
        @PrivAnnotation(value = {PrivEnum.USER,PrivEnum.ADMIN})
        public User queryUserById(int id) {
            return userDao.queryUserById(id);
        }
    }
    
  4. 切面类:

    @Component 
    @Aspect //添加该注解说明该类是一个切面类
    public class MyAspect {
        @Around(value = "execution(* cn.javasm.service..*.*(..))")
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
    
            //获取接口中的方法
            MethodSignature methodSnippet = (MethodSignature) proceedingJoinPoint.getSignature();
    		
            Method method1 = methodSnippet.getMethod();
            //1.获取目标对象
            Object target = proceedingJoinPoint.getTarget();
            System.out.println(target);
            //2.利用反射,根据目标对象获取目标方法  
            Method method = target.getClass().getMethod(method1.getName(), method1.getParameterTypes());
            //3. 如果方法上标记有注解则判断
            if(method.isAnnotationPresent(PrivAnnotation.class)){
                //3.1根据目标方法获取方法上面的注解
                PrivAnnotation annotation = method.getAnnotation(PrivAnnotation.class);
                PrivEnum[] value = annotation.value();
                //3.1.1如果注解中的值包含用户的角色值,则执行
                if(Arrays.asList(value).contains(TestDemo.role)){
                    return proceedingJoinPoint.proceed();
                }else{
                    //3.1.2如果不包含则抛出异常
                    throw  new RuntimeException("没有权限");
                }
            }else {
                //如果不包含注解,则放行
                return proceedingJoinPoint.proceed();
            }
        }
    }
    
  5. 测试:使用枚举类作为用户测试

    public class TestDemo {
        // cust  user  admin
        public static PrivEnum role = PrivEnum.ADMIN;
        public static void main(String[] args) {
    
            // 加载核心配置文件
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
            // 获取对象
            UserController userController = applicationContext.getBean(UserController.class);
            User user = new User(2, "猪八戒", "高老庄");
            userController.registUser(user);
            userController.updateUser(user);
            System.out.println(userController.queryUserById(1));
            userController.deleteUserById(2);
        }
    }
    
  6. 效果图

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值