罗展丰
Published on 2026-06-12 / 4 Visits
0
0

初始化能力使用指南

# 初始化能力使用指南

## 一、初始化机制概述

本项目提供统一的初始化能力,核心方式是继承 `AbstractInitializer` 类实现初始化逻辑。

**设计思想**:
- 所有初始化器统一管理,支持手动触发
- 支持执行顺序控制
- 支持成功/失败结果汇总
- 支持生命周期回调

---

## 二、创建初始化器

### 2.1 基础实现

继承 `AbstractInitializer` 并实现 `execute()` 方法:

```java
@Component
@Slf4j
public class YourDataInitializer extends AbstractInitializer {

    @Autowired
    private YourService yourService;

    @Override
    public String getName() {
        return "你的数据初始化";
    }

    @Override
    public void execute() {
        // 执行初始化逻辑
        log.info("开始执行初始化...");
        yourService.initData();
        log.info("初始化完成");
    }
}

2.2 设置执行顺序

使用 @Order 注解控制初始化顺序(数字越小越先执行):

@Order(1)
@Component
public class DepartmentInitializer extends AbstractInitializer {
    // 部门初始化(最先执行)
}

@Order(2)
@Component
public class RoleInitializer extends AbstractInitializer {
    // 角色初始化(在部门之后执行)
}

@Order(3)
@Component
public class UserInitializer extends AbstractInitializer {
    // 用户初始化(在角色之后执行)
}

2.3 生命周期回调

覆盖 onStart()onEnd() 方法:

@Component
@Slf4j
public class YourDataInitializer extends AbstractInitializer {

    @Override
    public String getName() {
        return "你的数据初始化";
    }

    @Override
    public void onStart() {
        super.onStart();
        log.info("初始化开始前的准备工作");
    }

    @Override
    public void execute() {
        log.info("执行初始化逻辑");
    }

    @Override
    public void onEnd(long costTime) {
        super.onEnd(costTime);
        log.info("初始化结束,耗时: {}ms", costTime);
    }
}

三、触发初始化

3.1 手动触发

调用 REST 接口触发所有初始化器:

POST /sys/v1/init/start
Content-Type: application/json

{}

请求参数

参数 类型 必填 说明
- - 当前接口不接受请求体参数

接口会执行全部初始化器

请求头

Header 说明
tenant-id String 租户ID(多租户场景下必填)
Authorization Bearer Token 认证令牌

请求示例

curl -X POST http://localhost:8080/sys/v1/init/start \
  -H "Content-Type: application/json" \
  -H "tenant-id: tenant001" \
  -H "Authorization: Bearer your_token_here" \
  -d '{}'

响应示例

{
    "code": 200,
    "data": {
        "success": ["部门初始化", "角色初始化", "用户初始化"],
        "fail": []
    },
    "message": "success"
}

3.2 执行流程

调用 /sys/v1/init/start
    ↓
遍历所有 AbstractInitializer Bean(按 @Order 排序)
    ↓
对每个初始化器执行:
    onStart()
        ↓
    execute()  ← 业务逻辑
        ↓
    onEnd(costTime)
    ↓
收集成功/失败结果
    ↓
返回汇总结果

四、完整示例

4.1 示例1:用户初始化器

@Component
@Slf4j
public class UserInitializer extends AbstractInitializer {

    @Autowired
    private UserService userService;

    @Override
    public String getName() {
        return "用户初始化";
    }

    @Override
    public void execute() {
        log.info("开始初始化用户数据...");
    
        // 检查是否已初始化(保证幂等性)
        if (userService.count() > 0) {
            log.info("用户数据已存在,跳过初始化");
            return;
        }

        // 创建默认用户
        UserEntity admin = new UserEntity();
        admin.setUserName("admin");
        admin.setPassword(PasswordEncoder.encode("admin123"));
        admin.setEmail("admin@example.com");
        userService.save(admin);

        log.info("用户初始化完成");
    }
}

4.2 示例2:部门初始化器

@Order(1)
@Component
@Slf4j
public class DepartmentInitializer extends AbstractInitializer {

    @Autowired
    private DepartmentService departmentService;

    @Override
    public String getName() {
        return "部门初始化";
    }

    @Override
    public void execute() {
        log.info("开始初始化部门数据...");
    
        if (departmentService.count() > 0) {
            log.info("部门数据已存在,跳过初始化");
            return;
        }

        // 创建默认部门
        DepartmentEntity dept = new DepartmentEntity();
        dept.setDeptName("总经办");
        dept.setParentId(0L);
        departmentService.save(dept);

        log.info("部门初始化完成");
    }
}

五、关键方法说明

方法 说明 是否必须实现
getName() 返回初始化器名称
execute() 执行初始化逻辑
onStart() 初始化开始前的回调
onEnd(long costTime) 初始化结束后的回调
doExecute() 模板方法,调用 onStart → execute → onEnd 内部调用

六、注意事项

  1. 幂等性:初始化逻辑应保证幂等,多次执行不产生副作用
  2. 异常处理execute() 方法抛出异常时,会被捕获并记录到失败列表,但不影响其他初始化器执行
  3. 顺序依赖:通过 @Order 注解控制初始化顺序,确保依赖的数据先被初始化
  4. 日志记录:在关键节点记录日志,便于排查问题
  5. Component 注解:必须添加 @Component 注解,否则不会被 Spring 扫描到

七、现有初始化器参考

项目中已有的初始化器:

初始化器 顺序 说明
DepartmentInitializer 1 部门数据初始化
RoleInitializer 2 角色数据初始化
UserInitializer 用户数据初始化

附录:特殊初始化方式

ApplicationReadyEvent(仅特殊场景使用)

在某些特殊场景下(如打印元数据初始化),需要在程序启动后自动执行初始化,可使用 @EventListener 注解:

@Configuration
public class PrintAutoConfiguration {

    @Bean
    public PrintInitialization printInitialization(...) {
        return new PrintInitialization(...);
    }

    @EventListener({ApplicationReadyEvent.class})
    public void init() {
        PrintInitialization printInit = SpringContextHolder.getBean(PrintInitialization.class);
        printInit.init();
    }
}

注意:这种方式仅限于框架级别的自动初始化,业务数据初始化应使用 AbstractInitializer 方式。