You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot:基于用户审计时如何将实体以‘System’身份保存?

解决方案

核心思路

问题根源在于定时任务线程没有活跃的会话作用域,直接依赖会话Bean会触发Scope 'session' is not active异常。只需修改AuditorAware的实现逻辑,让它同时支持**登录用户(会话上下文)和无用户(如定时任务)**两种场景,无用户时默认返回System作为审计者。

具体实现方案

方案1:兼容原有会话Bean的改造

如果需要保留原有的会话作用域用户Bean,可通过判断请求上下文或捕获异常来处理无会话场景:

@Component
public class AuditorAwareImpl implements AuditorAware<String> {
    @Autowired
    @Lazy // 懒加载避免启动时会话作用域初始化问题
    private SessionScopedUserBean sessionUser;

    @Override
    public Optional<String> getCurrentAuditor() {
        // 检查是否存在活跃的请求/会话上下文
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        if (requestAttributes != null) {
            try {
                String username = sessionUser.getUsername();
                return StringUtils.hasText(username) ? Optional.of(username) : Optional.of("System");
            } catch (IllegalStateException e) {
                // 会话作用域不活跃时返回System
                return Optional.of("System");
            }
        } else {
            // 无请求上下文(如定时任务)直接返回System
            return Optional.of("System");
        }
    }
}

方案2:基于Spring Security的简化实现(推荐)

如果你的项目使用Spring Security管理登录状态,可直接从SecurityContext获取用户,无需依赖会话Bean,逻辑更简洁:

@Component
public class AuditorAwareImpl implements AuditorAware<String> {
    @Override
    public Optional<String> getCurrentAuditor() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        
        // 判断是否为已认证的非匿名用户
        if (authentication != null 
            && authentication.isAuthenticated() 
            && !(authentication instanceof AnonymousAuthenticationToken)) {
            return Optional.of(authentication.getName());
        }
        
        // 无登录用户时返回System
        return Optional.of("System");
    }
}

关键注意事项

  • @Lazy注解:当依赖会话作用域Bean时,必须添加@Lazy,避免Spring启动时因无法初始化会话作用域Bean而报错。
  • 异常处理:直接依赖会话Bean时,务必捕获IllegalStateException(会话不活跃时抛出),确保逻辑不会中断。
  • 定时任务无需额外配置:修改AuditorAware后,定时任务中保存审计实体时会自动使用System作为审计者,无需在任务代码中手动设置。

是否需要调整原有方案?

不需要完全推翻原有审计机制,仅需修改AuditorAware的实现逻辑即可兼容两种场景。原有登录用户的审计逻辑不受影响,定时任务场景自动 fallback 到System身份,是最轻量化的解决方案。

内容的提问来源于stack exchange,提问作者Vitnem

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.23 01:24:30