package jnpf.audit.sdk; import jnpf.audit.AuditEventApi; import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.AutoConfiguration; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Bean; import org.springframework.core.env.Environment; /** * audit-sdk 自动装配(Task 7 Step 5)。 * *
注册机制:{@code META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports} * ——平台默认构建走 JDK21/boot3 profile(Spring Boot 3.5.7),Spring Boot 3 已移除 spring.factories * 的自动装配入口,必须用 {@code .imports};且该机制自 Spring Boot 2.7 起即受支持,对 boot2 profile 亦向后兼容。 * *
{@code audit.enabled}(默认 true,缺省视为启用)为总开关;置 false 时整套 Bean 不装配。 * 各 Bean 均加 {@link ConditionalOnMissingBean} 供宿主按需覆盖。 * *
层次现状(2026-08-11 起):SDK 侧只剩层 2({@code @AuditLog} 切面)与层 3
* ({@link AuditClient} 显式埋点)。层 1(MyBatis Executor 插件)已整套移除——它自交付起
* 一直默认关,{@code audit_events} 表内 {@code source_layer=1} 零行,属未启用即负债。
* 需要恢复见 {@code docs/handoff-2026-08-11-audit-into-biz-common.md} 记的 git revert 坐标。
*/
@AutoConfiguration
@ConditionalOnProperty(name = "audit.enabled", matchIfMissing = true)
public class AuditSdkAutoConfiguration {
@Bean
@ConditionalOnMissingBean
public AuditContextCollector auditContextCollector(Environment environment) {
return new AuditContextCollector(environment.getProperty("spring.application.name"));
}
/**
* spool 双层锁(Codex 批次二复验 #1/#2 终局修复):writer 与 replayer 共享同一实例,
* 把彼此的 spool 文件操作串行化(进程内 monitor + 跨进程 {@code spool.lock} FileLock)。
*/
@Bean
@ConditionalOnMissingBean
public AuditSpoolLock auditSpoolLock(
@Value("${audit.spool-dir:./audit-spool}") String spoolDir) {
return new AuditSpoolLock(spoolDir);
}
@Bean
@ConditionalOnMissingBean
public AuditSpoolWriter auditSpoolWriter(
@Value("${audit.spool-dir:./audit-spool}") String spoolDir,
AuditSpoolLock spoolLock) {
return new AuditSpoolWriter(spoolDir, spoolLock);
}
@Bean
@ConditionalOnMissingBean
public AuditEventPublisher auditEventPublisher(ObjectProvider