首页
/ RuoYi最佳实践:项目开发经验总结与分享

RuoYi最佳实践:项目开发经验总结与分享

2026-02-04 04:06:24作者:咎竹峻Karen

引言:为什么选择RuoYi作为企业级开发框架?

在企业级应用开发中,选择一个合适的快速开发框架至关重要。RuoYi(若依)作为基于SpringBoot的权限管理系统,以其简洁的架构设计、完善的权限控制和丰富的功能模块,成为了众多开发者的首选。本文将分享在实际项目中使用RuoYi框架的开发经验,帮助您更好地利用这一优秀框架。

RuoYi核心架构解析

模块化设计思想

RuoYi采用多模块Maven项目结构,每个模块职责明确:

graph TD
    A[ruoyi-admin] --> B[Web应用入口]
    A --> C[ruoyi-framework]
    A --> D[ruoyi-system]
    A --> E[ruoyi-quartz]
    A --> F[ruoyi-generator]
    A --> G[ruoyi-common]
    
    C --> H[核心框架]
    D --> I[系统模块]
    E --> J[定时任务]
    F --> K[代码生成]
    G --> L[通用工具]

技术栈深度分析

技术组件 版本 主要用途 优势
Spring Boot 2.5.15 应用框架 快速启动、自动配置
Apache Shiro 1.13.0 权限控制 轻量级、易扩展
MyBatis 集成 数据持久化 SQL可控性强
Druid 1.2.23 数据库连接池 监控功能强大
Thymeleaf 集成 模板引擎 天然支持Shiro标签

最佳实践:权限控制深度定制

数据权限精细化控制

RuoYi提供了完善的数据权限控制机制,通过@DataScope注解实现:

@DataScope(deptAlias = "d", userAlias = "u")
public List<SysUser> selectUserList(SysUser user) {
    return userMapper.selectUserList(user);
}

自定义权限验证逻辑

// 在Service层添加自定义权限验证
public String checkDataPermission(Long dataId) {
    // 获取当前用户
    SysUser currentUser = ShiroUtils.getSysUser();
    
    // 自定义权限验证逻辑
    if (!permissionService.hasDataPermission(currentUser.getUserId(), dataId)) {
        throw new ServiceException("无数据操作权限");
    }
    
    return "权限验证通过";
}

代码生成器的高级用法

自定义模板开发

RuoYi的代码生成器基于Velocity模板引擎,支持高度自定义:

## 自定义Entity模板
package ${packageName}.domain;

import java.io.Serializable;
import java.util.Date;
import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.core.domain.BaseEntity;

/**
 * ${functionName}实体类
 * 
 * @author ${author}
 * @date ${datetime}
 */
public class ${ClassName} extends BaseEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    
    #foreach ($column in $columns)
    /** $column.columnComment */
    #if($column.list)
    @Excel(name = "${column.columnComment}")
    #end
    private $column.javaType $column.javaField;
    
    #end
}

批量生成策略

// 批量生成代码示例
public void batchGenerateCode(List<GenTable> tables) {
    for (GenTable table : tables) {
        // 设置生成参数
        table.setTplCategory("crud");
        table.setPackageName("com.ruoyi.project");
        table.setModuleName("system");
        table.setBusinessName(table.getTableName());
        table.setFunctionName(table.getTableComment());
        
        // 执行生成
        GenUtils.generatorCode(table);
    }
}

性能优化实战经验

数据库查询优化

-- 使用索引优化查询
CREATE INDEX idx_user_dept_status ON sys_user(dept_id, status);
CREATE INDEX idx_oper_log_time ON sys_oper_log(oper_time);

-- 分页查询优化
SELECT * FROM sys_user 
WHERE dept_id = #{deptId} 
ORDER BY create_time DESC 
LIMIT #{offset}, #{pageSize};

缓存策略配置

# application.yml缓存配置
spring:
  cache:
    type: ehcache
    ehcache:
      config: classpath:ehcache/ehcache-shiro.xml

# Shiro缓存配置
shiro:
  cacheManager: ehCacheManager
  sessionManager:
    globalSessionTimeout: 1800000
    sessionValidationInterval: 1800000

安全加固措施

XSS攻击防护

// 自定义XSS过滤器
public class CustomXssFilter implements Filter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, 
                       FilterChain chain) throws IOException, ServletException {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        XssHttpServletRequestWrapper xssRequest = 
            new XssHttpServletRequestWrapper(httpRequest);
        chain.doFilter(xssRequest, response);
    }
}

SQL注入防护

// MyBatis参数处理
@Select("SELECT * FROM sys_user WHERE user_name = #{username}")
SysUser selectByUsername(@Param("username") String username);

// 使用预编译语句,避免字符串拼接

部署与监控最佳实践

多环境配置管理

# application-dev.yml 开发环境
server:
  port: 8080
  servlet:
    context-path: /ruoyi
spring:
  datasource:
    url: jdbc:mysql://localhost:3306/ry?useUnicode=true
    username: root
    password: 123456

# application-prod.yml 生产环境
server:
  port: 80
  servlet:
    context-path: /
spring:
  datasource:
    url: jdbc:mysql://prod-db:3306/ry?useUnicode=true
    username: prod_user
    password: ${DB_PASSWORD}

健康检查与监控

// 自定义健康检查端点
@Component
public class CustomHealthIndicator implements HealthIndicator {
    
    @Override
    public Health health() {
        // 检查数据库连接
        boolean dbConnected = checkDatabaseConnection();
        
        // 检查缓存状态
        boolean cacheAvailable = checkCacheStatus();
        
        if (dbConnected && cacheAvailable) {
            return Health.up().build();
        } else {
            return Health.down()
                .withDetail("database", dbConnected ? "connected" : "disconnected")
                .withDetail("cache", cacheAvailable ? "available" : "unavailable")
                .build();
        }
    }
}

常见问题解决方案

1. 权限配置不生效

问题分析:通常是由于Shiro配置或注解使用不当 解决方案

// 确保在ShiroConfig中正确配置
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean() {
    ShiroFilterFactoryBean shiroFilter = new ShiroFilterFactoryBean();
    shiroFilter.setSecurityManager(securityManager());
    
    // 添加权限配置
    Map<String, String> filterMap = new LinkedHashMap<>();
    filterMap.put("/system/user/**", "perms[system:user:view]");
    shiroFilter.setFilterChainDefinitionMap(filterMap);
    
    return shiroFilter;
}

2. 代码生成器模板修改不生效

解决方案

  1. 清理target目录
  2. 重新编译项目
  3. 检查模板文件路径是否正确

3. 性能瓶颈排查

使用Druid监控功能:

-- 查看慢SQL日志
SELECT * FROM sys_oper_log 
WHERE execute_time > 1000 
ORDER BY execute_time DESC;

扩展开发建议

微服务架构改造

graph TB
    subgraph "微服务架构"
        A[API Gateway] --> B[用户服务]
        A --> C[权限服务]
        A --> D[数据服务]
        A --> E[文件服务]
    end
    
    B --> F[MySQL]
    C --> G[Redis]
    D --> F
    E --> H[MinIO]

前端分离方案

建议采用RuoYi-Vue或RuoYi-React版本实现前后端分离,提升开发效率和用户体验。

总结与展望

RuoYi作为一个成熟的企业级开发框架,在实际项目中展现出了强大的灵活性和扩展性。通过本文分享的最佳实践,希望能够帮助开发者:

  1. 快速上手:理解框架核心架构和设计理念
  2. 深度定制:根据业务需求进行个性化开发
  3. 性能优化:掌握系统调优和监控方法
  4. 安全加固:构建安全可靠的应用系统

未来,随着技术的不断发展,RuoYi框架也将持续演进,为开发者提供更加完善的解决方案。建议关注官方更新,及时获取最新特性和安全补丁。

温馨提示:在实际项目开发中,建议建立完善的代码审查机制和自动化测试流程,确保代码质量和系统稳定性。


本文基于RuoYi 4.8.1版本编写,实际使用时请根据具体版本进行调整。

登录后查看全文
热门项目推荐
相关项目推荐