fix(core): 隔离 Spring Bean 名称,避免被前缀注解和相邻组件污染 - #344
Conversation
检测阶段已用注解边界确认 Bean,命名却仍用朴素前缀搜索,会从 BeanFactory 读到 decoy。 组件名称的宽捕获也会跨过右括号读到相邻注解。现在只从源码最靠前的准确注解参数里取值。 Co-authored-by: Cursor <cursoragent@cursor.com>
|
@lithe review |
Lithe Review结论: ⛔ 存在阻塞问题 变更理解本 PR 将 Bean/组件名称解析改为先定位精确注解,再通过 发现
验证
|
isolate_annotation_at 把字符串里的括号也计入深度,遇到 @bean("foo(") 会吞掉相邻注解。 括号扫描现在跟踪引号和转义,只对注解语法中的括号计数。 Co-authored-by: Cursor <cursoragent@cursor.com>
|
@lithe review |
Lithe Review结论: ✅ 未发现明确问题 LGTM 验证
|
1lck
left a comment
There was a problem hiding this comment.
发现 1 个阻塞的正确性回归:空的组件注解值会被当作实际 Bean 名称,导致合法的 @component("") 不再回退到默认类名。其余改动与 #315 的目标一致,现有 Rust Core 校验均通过。
| .and_then(|capture| capture.get(2)) | ||
| .map(|value| value.as_str().to_string()) | ||
| let start = earliest_component_annotation_start(context)?; | ||
| quoted_values(isolate_annotation_at(context, start)) |
There was a problem hiding this comment.
这里改用 quoted_values(...).next() 后,会接受空字符串,因为 quoted_values 的捕获组使用了 *。因此 @Component("") 返回 Some(""),bean_index 中的 unwrap_or(default_name) 不会执行,最终生成空 Bean 名和异常 ID。旧实现的捕获组使用 +,该场景会返回 None 并回退到类名。请过滤空值(或使用组件专用的非空提取逻辑),并补充 @Component("") 的单元与 spring.index 集成测试。
quoted_values 会接受空字符串,@component("") 变成 Some("") 后不再走类名回退。 现在忽略空捕获,与旧的非空捕获行为一致,避免空名称和异常 ID。 Co-authored-by: Cursor <cursoragent@cursor.com>
1lck
left a comment
There was a problem hiding this comment.
补充两条非阻塞的代码质量建议:1) 新增集成测试目前主要使用 contains / !contains,建议对完整 Bean 集合或至少数量与关键字段做更精确断言,避免遗漏未被显式排除的额外错误项;2) 删除重复的 assert_ne!,前面的 assert_eq!(..., Some("s")) 已经覆盖同一回归场景。
Summary
Fixes #315
Spring 索引在检测阶段已经用注解边界确认
@Bean和组件注解,但命名阶段仍保留两条宽松路径:bean_names使用find("@Bean"),会把@BeanFactory("decoy")误当成@Bean,返回decoycomponent_name用宽范围正则跨注解捕获,可能得到) @Component(本 PR 将命名逻辑与检测阶段对齐:只从准确匹配的注解、该注解自己的参数范围里提取名称;多个组件注解并存时,按源码位置最靠前的注解取值。
Changes
bean_names:改用SpringAnnotation::Bean.pattern().find()+isolate_annotation_at,替换find("@Bean")component_name:拆分“定位”和“参数解析”,新增earliest_component_annotation_start,按Match::start()选最靠前的组件注解COMPONENTS注释:数组顺序不决定胜者,只保证检测与命名支持范围一致spring.index集成测试,覆盖 issue 中的复现场景Test plan
@BeanFactory("decoy") @Bean("real")只返回real@BeanFactory("decoy")不生成 Bean@Service("s") @Component("c")返回s,不产生跨注解字符串@Component("c") @Service("s")返回c(验证不依赖COMPONENTS数组顺序)@Bean继续走默认 Bean 名称cargo test --manifest-path rust/Cargo.toml -p lithe-corescripts/verify-rust-core-comments.shcargo fmt --checkNotes
LazyLock缓存模式