ruoyi框架源码阅读之--Anonymous注解 允许 匿名访问不鉴权

Anonymous注解 允许 匿名访问不鉴权



前言

这个值得一看,好像还可以拿到其他项目直接用


一、Anonymous定义

package com.ruoyi.common.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 匿名访问不鉴权注解
 *
 * @author ruoyi
 */
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Anonymous {
}

二、注解配置

package com.ruoyi.framework.config.properties;

import java.util.*;
import java.util.regex.Pattern;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import com.ruoyi.common.annotation.Anonymous;

/**
 * 设置Anonymous注解 允许 匿名访问不鉴权
 * 项目初始化时候,会将Anonymous注解的 路径 提取出来,放到urls里面
 *
 * InitializingBean:为bean提供了初始化方法的方式,凡是继承该接口的类,在初始化bean的时候都会执行afterPropertiesSet方法
 *
 * ApplicationContextAware:当一个类实现了这个接口之后,这个类就可以方便的获得ApplicationContext对象(spring上下文)
 * ,Spring发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContext(参数)方法
 * ,调用该方法时,会将容器本身ApplicationContext对象作为参数传递给该方法。
 *
 * @author ruoyi
 */
@Configuration
public class PermitAllUrlProperties implements InitializingBean, ApplicationContextAware {
    private static final Pattern PATTERN = Pattern.compile("\\{(.*?)\\}");

    // spring上下文
    private ApplicationContext applicationContext;

    // 前端请求接口的时候,如果在这个url里面,直接放行
    private List<String> urls = new ArrayList<>();

    // 替代字符串
    public String ASTERISK = "*";

    @Override
    public void afterPropertiesSet() {

        // 将整个项目所有bean都拿出来
        RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);

        // 获取 每个url 与 方法、类的对应关系
        Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();

        // info 是代表每个url对象
        map.keySet().forEach(info -> {
             // 获取类和方法的信息
            HandlerMethod handlerMethod = map.get(info);

            // 获取方法上边的注解,如果此方法被“Anonymous”注解,则返回该方法,否则返回null
            Anonymous method = AnnotationUtils.findAnnotation(handlerMethod.getMethod(), Anonymous.class);
            // method为null啥也不干,否则替代path variable 为 *
            Optional.ofNullable(method).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));

            // 获取类上边的注解,如果此类被“Anonymous”注解,则返回该类,否则返回null
            Anonymous controller = AnnotationUtils.findAnnotation(handlerMethod.getBeanType(), Anonymous.class);
            // controller为null啥也不干,否则替代path variable 为 *
            Optional.ofNullable(controller).ifPresent(anonymous -> Objects.requireNonNull(info.getPatternsCondition().getPatterns())
                    .forEach(url -> urls.add(RegExUtils.replaceAll(url, PATTERN, ASTERISK))));
        });
    }

    /**
     * @Description // 这玩意是接口ApplicationContextAware带来的,就是为了在本类中方便获取 applicationContext
     * @Date 16:15 2023/3/22
     **/
    
    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        this.applicationContext = context;
    }

    public List<String> getUrls() {
        return urls;
    }

    public void setUrls(List<String> urls) {
        this.urls = urls;
    }
}

三、Debug讲解

1、看看根据上下文获取到的是个啥,这个是获取到所有接口的 【访问路径:接口地址路径】
在这里插入图片描述
2、遍历获取每个路径的方法
在这里插入图片描述
3、判断当前方法有没有Anonymous注解哇
在这里插入图片描述
在这里插入图片描述
4、被Anonymous注解修饰的,将根据正则替换 链接字符串
在这里插入图片描述
5、最后 Security配置类中把 urls 中的访问地址给全部放行
在这里插入图片描述


总结

说不定会用的到,记录一下
  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
好的,下面是使用Ruoyi框架实现Sharding-JDBC分表的步骤: 1. 引入Sharding-JDBC依赖 在pom.xml文件中添加Sharding-JDBC的依赖: ```xml <dependency> <groupId>org.apache.shardingsphere</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>4.1.1</version> </dependency> ``` 2. 配置数据源 在application.yml中配置数据源信息,如下所示: ```yaml spring: datasource: # 主库 master: url: jdbc:mysql://localhost:3306/db_master?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver # 从库 slave: url: jdbc:mysql://localhost:3306/db_slave?serverTimezone=UTC&useSSL=false&characterEncoding=utf-8 username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver shardingsphere: datasource: names: master,slave # 配置主从库 master-slave-rules: ms: master-data-source-name: master slave-data-source-names: slave load-balance-algorithm-type: round_robin # 配置数据分片规则 sharding: tables: user_info: # 分库键 database-strategy: inline: sharding-column: user_id algorithm-expression: ds${user_id % 2} # 分表键 table-strategy: inline: sharding-column: order_id algorithm-expression: t_order_${order_id % 2} actual-data-nodes: master.user_info_$->{0..1} key-generator: column: id type: SNOWFLAKE ``` 3. 创建数据表 创建两个数据库db_master和db_slave,每个数据库中创建user_info表,表结构如下: ```sql CREATE TABLE `user_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `user_id` bigint(20) NOT NULL COMMENT '用户ID', `order_id` bigint(20) NOT NULL COMMENT '订单ID', `name` varchar(50) NOT NULL COMMENT '姓名', `age` int(11) NOT NULL COMMENT '年龄', `address` varchar(200) DEFAULT NULL COMMENT '地址', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户信息表'; ``` 4. 创建Mapper接口 在Ruoyi框架中,通常使用MyBatis-Plus进行数据库操作,因此需要创建对应的Mapper接口,如下所示: ```java public interface UserInfoMapper extends BaseMapper<UserInfo> { } ``` 5. 测试分库分表 在代码中使用Sharding-JDBC进行数据库操作,如下所示: ```java @Service public class UserServiceImpl implements IUserService { @Autowired private UserInfoMapper userInfoMapper; @Override public void addUser(UserInfo userInfo) { userInfoMapper.insert(userInfo); } @Override public List<UserInfo> getUserList() { return userInfoMapper.selectList(null); } } ``` 以上就是使用Ruoyi框架实现Sharding-JDBC分表的步骤。需要注意的是,Sharding-JDBC不支持使用MyBatis-Plus的自动填充功能,因此需要手动设置分表键的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

练习两年半的攻城狮

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值