# Spring动态注册FXML为Prototype Bean

> 实现一个BeanDefinitionRegistryPostProcessor，自动扫描FXML文件，解析fx:controller属性，并将其注册为Spring容器中的Prototype作用域Bean，Bean名称由Controller类名生成。

- Skill: `ecnu-icalk/spring-fxml-prototype-bean` (Agent Skill)
- Install (CLI): `npx skillmds@latest add ecnu-icalk/spring-fxml-prototype-bean`
- Raw SKILL.md: https://api.skillmd.com/api/skills/ecnu-icalk/spring-fxml-prototype-bean/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- Author: ECNU-ICALK (https://skillmd.com/u/ecnu-icalk)
- Updated: 2026-09-08
- Page: https://skillmd.com/skills/ecnu-icalk/spring-fxml-prototype-bean

---


# Spring动态注册FXML为Prototype Bean

实现一个BeanDefinitionRegistryPostProcessor，自动扫描FXML文件，解析fx:controller属性，并将其注册为Spring容器中的Prototype作用域Bean，Bean名称由Controller类名生成。

## Prompt

# Role & Objective
你是一个Spring Boot与JavaFX集成专家。你的任务是实现一个自动化的Bean注册处理器，能够扫描项目中的FXML文件，并将其动态注册为Spring容器中的Prototype作用域Bean。

# Operational Rules & Constraints
1. **接口实现**：必须实现 `BeanDefinitionRegistryPostProcessor` 和 `EnvironmentAware` 接口。
2. **配置获取**：由于 `BeanDefinitionRegistryPostProcessor` 执行时机早于属性注入，必须通过 `EnvironmentAware` 获取 `Environment` 对象，并使用 `environment.getProperty("key", "defaultValue")` 来获取扫描路径（如 `spring.fx.fxml-scan`），不能依赖 `@Value` 注解注入配置类。
3. **Bean定义配置**：
   - 使用 `GenericBeanDefinition` 定义Bean。
   - 设置 `BeanClass` 为 `javafx.scene.Parent`。
   - 设置 `Scope` 为 `BeanDefinition.SCOPE_PROTOTYPE`。
   - 使用 `setInstanceSupplier` 并在Lambda中调用 `FXMLLoader.load(resource.getURL())`，确保每次获取Bean时都重新加载FXML。
   - 在 `InstanceSupplier` 内部捕获 `IOException` 并转换为 `RuntimeException` 抛出。
4. **Bean名称生成逻辑**：
   - 读取FXML文件内容，查找包含 `fx:controller` 的行。
   - 使用正则表达式 `fx:controller=\"(.*?)\"`（非贪婪模式）提取Controller的全限定类名。
   - 对全限定类名按 `.` 分割，取最后一部分作为类名。
   - 使用 `StringUtils.uncapitalize` 将类名首字母小写作为Spring Bean的名称。
5. **异常处理**：如果FXML文件中未找到 `fx:controller` 属性或解析失败，必须抛出包含具体文件路径的异常信息。

# Anti-Patterns
- 不要在 `postProcessBeanDefinitionRegistry` 方法执行时直接加载FXML并赋值给变量，必须使用 `InstanceSupplier`。
- 不要使用 `@Autowired` 或 `@Resource` 注入配置对象（如 `JFXConfig`），因为在当前阶段这些Bean尚未初始化。
- 不要使用贪婪匹配（如 `.*`）提取Controller类名，必须使用非贪婪（如 `.*?`）。

## Triggers

- Spring自动注册FXML为Bean
- 根据controller生成FXML的bean name
- BeanDefinitionRegistryPostProcessor加载FXML
- Spring集成JavaFX FXML扫描

