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

Spring Bean循环依赖问题:UserRepositoryImpl自注入异常排查

问题:Spring Bean循环依赖(自注入假象)

开发REST API应用时遇到Bean循环依赖错误,明明UserRepositoryImpl类里没有自身类型的字段,只依赖UserRepository接口和UserDomainConverter组件,但日志显示userRepositoryImpl存在循环依赖。

相关代码

UserRepositoryImpl类

@Repository
public class UserRepositoryImpl {

private final UserRepository repository;

private final UserDomainConverter converter;

@Autowired
public UserRepositoryImpl(UserRepository repository,
                          UserDomainConverter converter) {
    this.repository = repository;
    this.converter = converter;
}

//some methods
}

UserDomainConverter类

@Component
public class UserDomainConverter {

//some methods
}

UserRepository接口

@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long> {
    Optional<UserEntity> findByAuthToken(String authToken);

Optional<UserEntity> findByNickname(String nickname);

List<UserEntity> findUserEntitiesByIdIn(List<Long> idList);

List<UserEntity> findUserEntitiesByNicknameIn(String nickname);
}

错误日志

2022-09-14 23:56:06.379  INFO 21408 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2022-09-14 23:56:06.387  INFO 21408 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-09-14 23:56:06.403 ERROR 21408 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

The dependencies of some of the beans in the application context form a cycle:

   userController defined in file [D:\IdeaProjects\sigma-internship\target\classes\spotylike\spotylike\controller\UserController.class]
      ↓
   userService defined in file [D:\IdeaProjects\sigma-internship\target\classes\spotylike\spotylike\service\UserService.class]
┌─────┐
|  userRepositoryImpl defined in file [D:\IdeaProjects\sigma-internship\target\classes\spotylike\spotylike\repository\impl\UserRepositoryImpl.class]
└─────┘


Action:

Relying upon circular references is discouraged and they are prohibited by default. Update your application to remove the dependency cycle between beans. As a last resort, it may be possible to break the cycle automatically by setting spring.main.allow-circular-references to true.


Process finished with exit code 1
解决方案

问题根因

这是Spring Data JPA的默认命名规则导致的隐式循环依赖:
Spring Data JPA会自动为继承JpaRepository的接口生成代理实现类,默认规则是接口名+Impl。你给UserRepositoryImpl加了@Repository注解,Spring会把它当成UserRepository接口的自定义实现类。

当创建UserRepositoryImpl的Bean时,它需要注入UserRepository,此时Spring会返回你的UserRepositoryImpl本身(因为它被识别为接口的实现),于是形成了循环:UserRepositoryImpl依赖UserRepository,而UserRepository的实际实现就是UserRepositoryImpl。

修复方案

方案一:调整类名和结构(推荐)

修改自定义实现类的名称,避免和默认命名规则冲突,同时通过自定义接口分离方法:

// 定义自定义方法的接口
public interface UserRepositoryCustom {
    // 在这里声明你的自定义方法
}

// 修改实现类名称并实现自定义接口
@Repository
public class UserRepositoryCustomImpl implements UserRepositoryCustom {
    private final UserRepository repository;
    private final UserDomainConverter converter;

    @Autowired
    public UserRepositoryCustomImpl(UserRepository repository, UserDomainConverter converter) {
        this.repository = repository;
        this.converter = converter;
    }

    // 实现自定义方法
}

// 让原接口继承自定义接口
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Long>, UserRepositoryCustom {
    // 原有查询方法
}

方案二:指定Bean名称

如果不想改类名,给UserRepositoryImpl的@Repository注解指定唯一名称,避免Spring把它识别为UserRepository的实现:

@Repository("customUserRepository")
public class UserRepositoryImpl {
    // 类内容保持不变
}

这样Spring注入UserRepository时,会使用自动生成的代理类,而不是你的UserRepositoryImpl。

方案三:临时允许循环依赖(不推荐)

仅作为临时调试手段,在配置文件中添加:

# application.properties
spring.main.allow-circular-references=true

这只是绕过问题,不是根本解决方式,不建议长期使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:01:16