news 2026/2/16 20:48:46

注意模块是否引入

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
注意模块是否引入

你问“没有权限吗?”,结合之前的日志和上下文(访问/processDefinition/list/processDefinition/uploadStreamAndDeployment报 404),我们来深入分析:这个问题是“没有权限”还是“接口根本不存在”?


🔍 一、先判断:是「权限问题」还是「接口未映射」?

❌ 当前错误不是“权限问题”,而是:

接口根本没有被 Spring 注册!

证据来自你的日志:
org.springframework.web.servlet.resource.NoResourceFoundException: No static resource processDefinition/uploadStreamAndDeployment. ... at FrameworkServlet.doPost(...)

这个异常说明:

关键点含义
NoResourceFoundExceptionSpring 的 DispatcherServlet 找不到任何处理器(Controller)来处理该请求
最终落到ResourceHttpRequestHandler尝试当作静态资源(如 JS/CSS)加载,失败
没有进入拦截器或认证逻辑请求压根没进安全层(如 Spring Security)

👉结论:这不是权限问题(403 Forbidden),而是路径不存在(404 Not Found)的变种。

✅ 真正的“无权限”错误会显示:

  • 403 Forbidden
  • 日志中出现AccessDeniedException
  • 请求进入了 Security 过滤链

✅ 二、你现在的问题本质

问题当前状态
接口是否存在?❌ 不存在(Controller 没注册或路径写错)
是否需要登录才能访问?⚠️ 还没到那一步(还没启用权限控制)
是认证问题吗?❌ 不是
能通过 Postman 直接调通吗?❌ 不能,因为接口根本没暴露

✅ 三、如何确认是不是“权限”导致的?

方法 1:查看是否引入了权限框架

检查pom.xmlbuild.gradle

<!-- 如果有这行,才可能涉及权限 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-security</artifactId></dependency>

如果没有 →根本没有权限控制机制→ 不可能是“没权限”


方法 2:查看是否有安全配置类

搜索项目中是否有:

  • WebSecurityConfigurerAdapter(旧版)
  • @EnableWebSecurity
  • 自定义过滤器、JWT 验证等

👉 如果都没有 → 权限系统未启用 → 所有人默认可访问所有接口


方法 3:测试一个已知存在的接口

比如你加了一个测试接口:

@GetMapping("/hello")publicStringhello(){return"ok";}

然后访问:

GET http://localhost:8081/hello
  • ✅ 能访问 → 说明服务正常,无需登录
  • ❌ 不能访问(跳转 /login 或返回 403)→ 启用了 Security,默认保护所有接口

🛠️ 四、你应该怎么做?

第一步:先让接口存在 ✅(当前最紧急)

确保你有以下代码:

@RestController@RequestMapping("/processDefinition")publicclassProcessDefinitionController{@GetMapping("/list")publicObjectlist(){// TODO 实现查询逻辑return"under construction";}@PostMapping("/uploadStreamAndDeployment")publicObjectupload(@RequestParam("file")MultipartFilefile){// TODO 实现部署逻辑return"uploaded: "+file.getOriginalFilename();}}

✅ 启动后看日志是否输出:

Mapped "{[/processDefinition/list],methods=[GET]}" onto ... Mapped "{[/processDefinition/uploadStreamAndDeployment],methods=[POST]}" onto ...

第二步:再考虑“权限控制”🔐

当你确认接口可以正常访问后,再决定:

需求解决方案
所有人都能访问这些接口?不加权限即可
只允许管理员操作?添加 Spring Security + 角色控制
需要登录用户才能上传流程?使用 JWT / Session 认证
示例:限制只有 ADMIN 可以上传
@PreAuthorize("hasRole('ADMIN')")@PostMapping("/uploadStreamAndDeployment")publicObjectupload(...){...}

⚠️ 前提是你已经配置了 Spring Security 并集成了用户认证体系。


✅ 五、典型权限错误 vs 当前错误对比

类型HTTP 状态码异常信息是否进 Controller
接口不存在404NoResourceFoundException❌ 没进
无权限访问403AccessDeniedException✅ 进了,但被拒绝
未登录401Unauthorized❌ 被拦截在门外

你现在是第一种情况 ——接口都没建好,谈不上有没有权限。


✅ 六、总结回答:“没有权限吗?”

不是。你遇到的问题不是“没有权限”,而是“接口根本没注册成功”。

🔧解决步骤如下:

  1. ✅ 添加ProcessDefinitionController控制器类
  2. ✅ 正确实现两个接口:/list/uploadStreamAndDeployment
  3. ✅ 检查包结构,确保被 Spring 扫描到
  4. ✅ 查看启动日志,确认Mapped日志出现
  5. ✅ 用 Postman 测试能否直接访问(不登录)
  6. ✅ 成功后再考虑是否添加权限控制

💬 最后建议

如果你希望我帮你:

  • 生成完整的带权限控制的Controller
  • 添加 Spring Security 登录认证
  • 实现基于 JWT 的流程管理权限体系

请告诉我你的技术栈:

  • 是否使用 Spring Security?
  • 是否已有用户登录系统?
  • 前端是 Vue/React 还是内部调用?

注意模块是否引入

<!-- activiti模块--><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-activiti</artifactId></dependency><!-- 工作流模块--><dependency><groupId>com.ruoyi</groupId><artifactId>ruoyi-workflow</artifactId></dependency>

你想搞清楚 MyBatis、MyBatis-Spring、MyBatis-Spring-Boot 这三者的核心区别,本质是要理解原生框架 → Spring 整合适配 → Spring Boot 自动配置的三层演进关系,我会用通俗的语言+核心差异点帮你梳理清楚。

一、核心定位(一句话总结)

组件核心定位
MyBatis基础 ORM 框架,独立实现 SQL 映射、参数处理、结果集映射等核心功能(无 Spring 依赖)
MyBatis-Spring适配层/整合包,让 MyBatis 能融入 Spring 生态(解决和 Spring 容器、事务的集成)
MyBatis-Spring-BootSpring Boot 场景下的自动配置包,基于 MyBatis-Spring 进一步简化配置(零/少配置启动)

二、详细区别与使用场景

1. MyBatis(原生核心)
  • 本质:独立的 ORM 框架,不依赖任何 Spring 组件,可单独使用(比如纯 JavaSE 项目)。
  • 核心功能
    • 定义 Mapper 接口和 XML/注解式 SQL;
    • 提供SqlSessionFactorySqlSession等核心类操作数据库;
    • 处理 SQL 参数、结果集映射、动态 SQL、缓存等。
  • 使用方式(原生)
    需手动创建SqlSessionFactory,手动管理SqlSession生命周期,示例:
    // 原生 MyBatis 手动配置Stringresource="mybatis-config.xml";InputStreaminputStream=Resources.getResourceAsStream(resource);// 手动创建 SqlSessionFactorySqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream);// 手动获取 SqlSession 执行 SQLtry(SqlSessionsession=sqlSessionFactory.openSession()){UserMappermapper=session.getMapper(UserMapper.class);Useruser=mapper.selectById(1);}
  • 缺点:在 Spring 项目中使用时,需手动整合 Spring 容器、事务管理,开发繁琐。
2. MyBatis-Spring(Spring 整合适配)
  • 本质:MyBatis 官方提供的 Spring 整合包(依赖 Spring Core、Spring JDBC 等),是 MyBatis 和 Spring 之间的“桥梁”。
  • 核心解决的问题
    1. 将 MyBatis 的SqlSessionFactory交由 Spring 容器管理(单例 Bean);
    2. 将 Mapper 接口代理对象注入到 Spring 容器中(可通过@Autowired注入);
    3. 整合 Spring 事务(让 MyBatis 操作参与 Spring 声明式事务);
    4. 自动管理SqlSession生命周期(无需手动创建/关闭)。
  • 使用方式(Spring 项目)
    需在 Spring XML/配置类中手动配置SqlSessionFactoryMapperScannerConfigurer等 Bean:
    // Spring 配置类整合 MyBatis(MyBatis-Spring 方式)@ConfigurationpublicclassMyBatisConfig{// 配置 SqlSessionFactory(交由 Spring 管理)@BeanpublicSqlSessionFactorysqlSessionFactory(DataSourcedataSource)throwsException{SqlSessionFactoryBeanfactoryBean=newSqlSessionFactoryBean();factoryBean.setDataSource(dataSource);// 手动指定 Mapper 位置factoryBean.setMapperLocations(newPathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));returnfactoryBean.getObject();}// 扫描 Mapper 接口,生成代理 Bean@BeanpublicMapperScannerConfigurermapperScannerConfigurer(){MapperScannerConfigurerconfigurer=newMapperScannerConfigurer();configurer.setBasePackage("com.example.mapper");// Mapper 接口包路径returnconfigurer;}}
  • 特点:适配 Spring 生态,但仍需手动配置核心 Bean,适合传统 Spring 项目(非 Boot)。
3. MyBatis-Spring-Boot(Spring Boot 自动配置)
  • 本质:基于 MyBatis-Spring 封装的 Spring Boot Starter,核心是“自动配置”,减少手动配置。
  • 核心解决的问题
    1. 自动检测数据源,自动创建SqlSessionFactoryBean;
    2. 自动扫描 Mapper 接口(默认扫描主类所在包下的 Mapper);
    3. 支持通过application.yml/application.properties配置 MyBatis 参数(无需写配置类);
    4. 完全兼容 MyBatis-Spring 的功能,且配置更简洁。
  • 使用方式(Spring Boot 项目)
    仅需引入依赖 + 少量配置即可:
    <!-- 引入 MyBatis-Spring-Boot-Starter --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.3.0</version></dependency>
    # application.yml 配置(无需写配置类)mybatis:mapper-locations:classpath:mapper/*.xml# 指定 Mapper XML 位置type-aliases-package:com.example.entity# 实体类别名包configuration:map-underscore-to-camel-case:true# 开启下划线转驼峰
    Mapper 接口仅需加@Mapper注解(或主类加@MapperScan):
    @Mapper// 标记为 MyBatis Mapper,Spring Boot 自动扫描并创建代理 BeanpublicinterfaceUserMapper{UserselectById(Longid);}// 业务层直接注入使用@ServicepublicclassUserService{@AutowiredprivateUserMapperuserMapper;// 自动注入,无需手动配置}
  • 特点:零/少配置即可使用,符合 Spring Boot “约定大于配置”的理念,是目前最主流的使用方式。

三、三者的依赖关系

MyBatis(核心)

MyBatis-Spring(整合层)

MyBatis-Spring-Boot(自动配置层)

  • MyBatis-Spring 依赖 MyBatis 核心包,不能单独使用;
  • MyBatis-Spring-Boot 依赖 MyBatis-Spring,是更高层的封装,最终还是基于 MyBatis 核心功能。

四、使用场景选择

场景推荐使用
纯 JavaSE 项目(无 Spring)MyBatis 原生
传统 Spring 项目(XML/配置类)MyBatis + MyBatis-Spring
Spring Boot 项目MyBatis-Spring-Boot(首选)

总结

  1. MyBatis是基础核心,提供 ORM 核心能力,无框架依赖;
  2. MyBatis-Spring是适配层,解决 MyBatis 与 Spring 容器、事务的集成问题;
  3. MyBatis-Spring-Boot是 Spring Boot 场景的简化版,基于 MyBatis-Spring 实现自动配置,大幅减少配置工作量。

核心记忆点:三者是基础 → 整合 → 简化的关系,实际开发中 Spring Boot 项目直接用 MyBatis-Spring-Boot 即可,底层会自动整合 MyBatis-Spring 和 MyBatis 核心。

你现在遇到的核心问题是 Spring 容器中缺少org.activiti.engine.HistoryService类型的 Bean,导致ActivitiHistoryServiceImpl里的historyService字段无法完成自动注入。结合若依(RuoYi)框架的特性,我会给出适配若依的精准解决方案,分步骤帮你解决:

一、先明确问题根源(若依场景专属)

若依框架集成 Activiti 时,默认不会自动注册HistoryService等 Activiti 核心服务 Bean,原因是:

  1. Activiti 的核心服务(HistoryService/TaskService/RuntimeService 等)不是 Spring 自动扫描的 Bean,需要通过ProcessEngine手动获取并注册;
  2. 若依的 Activiti 配置可能缺失了“暴露核心服务 Bean”的步骤,导致容器中没有HistoryService

二、适配若依的解决方案(完整可直接用)

步骤 1:检查若依的 Activiti 配置类

若依项目中通常有ActivitiConfig配置类(路径一般是com.ruoyi.framework.configcom.ruoyi.activiti.config),先补充以下配置,手动注册HistoryServiceBean:

importorg.activiti.engine.HistoryService;importorg.activiti.engine.ProcessEngine;importorg.activiti.engine.ProcessEngineConfiguration;importorg.activiti.engine.RuntimeService;importorg.activiti.engine.TaskService;importorg.activiti.engine.spring.SpringProcessEngineConfiguration;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.jdbc.datasource.DataSourceTransactionManager;importorg.springframework.transaction.PlatformTransactionManager;importjavax.sql.DataSource;/** * 若依框架 Activiti 核心配置(补充 HistoryService 等 Bean 注册) */@ConfigurationpublicclassActivitiConfig{// 注入若依框架已配置好的数据源(无需重复配置,复用项目默认数据源)@AutowiredprivateDataSourcedataSource;/** * 事务管理器(复用 Spring 事务,Activiti 必须依赖) */@BeanpublicPlatformTransactionManagertransactionManager(){returnnewDataSourceTransactionManager(dataSource);}/** * 初始化 Activiti 流程引擎配置(适配若依数据源) */@BeanpublicProcessEngineConfigurationprocessEngineConfiguration(){SpringProcessEngineConfigurationconfiguration=newSpringProcessEngineConfiguration();// 关联若依的数据源configuration.setDataSource(dataSource);// 关联事务管理器configuration.setTransactionManager(transactionManager());// 自动更新 Activiti 数据库表(若依项目首次运行需开启,后续可改为 false)configuration.setDatabaseSchemaUpdate("true");// 关闭异步执行器(避免若依启动时的额外异常)configuration.setAsyncExecutorActivate(false);// 解决若依中 Activiti 字体显示问题(可选,但建议加)configuration.setActivityFontName("宋体");configuration.setLabelFontName("宋体");configuration.setAnnotationFontName("宋体");returnconfiguration;}/** * 核心:创建 ProcessEngine(Activiti 引擎入口) */@BeanpublicProcessEngineprocessEngine(){returnprocessEngineConfiguration().buildProcessEngine();}/** * 注册 HistoryService Bean 到 Spring 容器(解决注入失败的核心) */@BeanpublicHistoryServicehistoryService(){returnprocessEngine().getHistoryService();}// 可选:注册其他 Activiti 核心服务(若依中可能用到)@BeanpublicRuntimeServiceruntimeService(){returnprocessEngine().getRuntimeService();}@BeanpublicTaskServicetaskService(){returnprocessEngine().getTaskService();}}
步骤 2:检查若依的依赖配置(pom.xml)

确保若依项目中引入了正确的 Activiti 依赖,且版本和若依的 Spring Boot 版本兼容(若依 3.x 通常基于 Spring Boot 2.x,推荐 Activiti 7.1.0.M6):

<!-- Activiti 核心依赖(适配若依 Spring Boot 2.x) --><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.1.0.M6</version><!-- 排除冲突依赖(若依已自带,避免重复) --><exclusions><exclusion><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId></exclusion></exclusions></dependency>
步骤 3:验证配置生效(关键)
  1. 确保ActivitiConfig类被 Spring 扫描到:
    • 检查类上是否有@Configuration注解;
    • 检查若依的主启动类(RuoYiApplication)是否扫描到该配置包(比如@SpringBootApplication(scanBasePackages = "com.ruoyi"))。
  2. 清理并重启若依项目:
    # 若依是 Maven 项目,执行清理命令mvn clean compile
  3. 启动项目后,查看日志是否有HistoryService相关的 Bean 创建日志,无NoSuchBeanDefinitionException即说明生效。

三、若依场景常见坑点排查

如果仍报错,按以下顺序排查:

  1. 数据源冲突:若依可能配置了多数据源,需确保 Activiti 用的是正确的数据源(上述配置已复用若依默认数据源,一般无需改);
  2. 包扫描问题ActivitiConfig所在包未被@SpringBootApplication扫描,需手动指定扫描包;
  3. Activiti 版本冲突:若依自带的 MyBatis、Spring 版本和 Activiti 不兼容,需调整 Activiti 版本(比如降级到 6.0.0);
  4. 若依权限拦截:若依的权限框架(Shiro/Spring Security)拦截了 Activiti 核心 Bean,需在权限配置中放行 Activiti 相关包。

总结

  1. 核心问题:若依框架中未手动注册HistoryServiceBean,导致 Spring 容器找不到该类型;
  2. 解决关键:在ActivitiConfig中通过ProcessEngine创建并暴露HistoryServiceBean;
  3. 适配要点:复用若依的数据源和事务管理器,避免依赖冲突,确保配置类被扫描到。

按上述步骤配置后,若依项目中的ActivitiHistoryServiceImpl就能正常注入HistoryService了。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/10 11:44:26

AI时代,测试工程师如何转型产品经理?

一、引言&#xff1a;AI时代的转型机遇与测试工程师的独特优势 在人工智能技术迅猛发展的背景下&#xff0c;产品经理角色正经历深刻变革&#xff0c;AI产品经理成为行业新风口。对于软件测试从业者而言&#xff0c;转型并非遥不可及——测试工作中积累的系统性思维、细节把控…

作者头像 李华
网站建设 2026/2/16 16:33:16

从功能测试到AI淘金:一个测试工程师的副业觉醒

心数据&#xff1a;2025年全球AI测试工具市场规模突破$7.8亿&#xff08;Gartner&#xff09;&#xff0c;而中国软件测试从业者平均薪资仅1.8万元/月&#xff08;智联招聘&#xff09; 一、主业困局&#xff1a;测试工程师的职场天花板 技术代际断层 graph LR A[手工测试]--&g…

作者头像 李华
网站建设 2026/2/15 5:07:52

救命神器9个一键生成论文工具,继续教育学生轻松搞定论文!

救命神器9个一键生成论文工具&#xff0c;继续教育学生轻松搞定论文&#xff01; AI 工具如何成为论文写作的得力助手 在当前继续教育学生面临论文写作压力日益增大的背景下&#xff0c;AI 工具逐渐成为不可或缺的辅助工具。这些工具不仅能够帮助用户快速生成内容&#xff0c;还…

作者头像 李华
网站建设 2026/2/3 18:57:14

告别配图焦虑:Nano Banana Pro 深度实战

大家好&#xff0c;我是悟鸣。 最近有很多朋友问我&#xff1a;“你最近的很多文章的配图挺漂亮的&#xff0c;用什么模型&#xff1f;用什么提示词&#xff1f;” 如介绍“官方文档 Skill ”的图。 如介绍“通俗讲解 Skill ”的图。 这篇文章给大家分享一下流程&#xff0c;…

作者头像 李华
网站建设 2026/2/12 14:21:23

每日面试题分享153:JVM垃圾回收调优的目标是什么?

JVM垃圾回收调优的目标有两个&#xff0c;低延迟和高吞吐量。但通常这两个目标是互斥的&#xff0c;需要根据业务场景做取舍。低延迟指的是每次GC的停顿时间短&#xff0c;保证系统响应能力。比如在实时交易系统、游戏、即时通讯系统中&#xff0c;对系统响应能力要求很高&…

作者头像 李华
网站建设 2026/2/16 1:18:00

2026 程序员薪资详情:分经验 / 技术方向(含网络安全)薪资水平

前言 程序员&#xff0c;数字时代的建筑师&#xff0c;他们的代码构建着我们日常生活的方方面面。 他们的薪资也一直是大众好奇的焦点。本文将结合最新数据&#xff0c;深入分析程序员工资水平&#xff0c;揭秘代码背后的价值。 一、平均薪资&#xff1a;高于平均水平&#x…

作者头像 李华