*************************** APPLICATION FAILED TO START *************************** Description: The dependencies of some of the beans in the application context form a cycle: firTestController ┌─────┐ | userServiceImpl ↑ ↓ | systemServiceImpl └─────┘ 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. Disconnected from the target VM, address: '127.0.0.1:55987', transport: 'socket'
// IUserService 接口 public interface IUserService { void getUserInfo(); } // UserServiceImpl 类实现 IUserService 接口 @Component public class UserServiceImpl implements IUserService { @Autowired private ISystemService systemService; @Override public void getUserInfo() { System.out.println("Get user info"); } } // ISystemService 接口 public interface ISystemService { void getSystemInfo(); } // SystemServiceImpl 类实现 ISystemService 接口 @Component public class SystemServiceImpl implements ISystemService { @Autowired private IUserService userService; @Override public void getSystemInfo() { System.out.println("Get system info"); } } // FirTestController 类 @Component public class FirTestController { @Autowired private IUserService userService; }
提供的例子中,存在循环依赖的原因如下:
UserServiceImpl 依赖于 ISystemService 接口,它的字段 systemService 被 @Autowired 注解注入。
SystemServiceImpl 类实现了 ISystemService 接口,它的字段 userService 被 @Autowired 注解注入。
FirTestController 类依赖于 IUserService 接口,它的字段 userService 被 @Autowired 注解注入。
这样,一个循环的依赖链就形成了:
UserServiceImpl 依赖于 ISystemService
SystemServiceImpl 依赖于 IUserService
FirTestController 依赖于 IUserService
当 Spring 容器启动时,它会尝试解析和创建这些 bean。在解析 UserServiceImpl 时,它会注入一个 ISystemService 实例,而这个实例是 SystemServiceImpl。在解析 SystemServiceImpl 时,它会注入一个 IUserService 实例,而这个实例是 UserServiceImpl。这样就形成了一个循环的依赖链,导致 Spring 容器无法成功创建这些 bean,最终抛出循环依赖的异常。
/** * 用户 接口层 */ private IUserService iUserService; @Autowired public void setUserService(@Lazy IUserService iUserService) { this.iUserService = iUserService; }
采用了 @Lazy 注解来解决循环依赖的问题,这是一种有效的方式。通过将 @Lazy 注解添加到 setUserService 方法上,延迟了 IUserService bean 的初始化,避免了在初始化 UserServiceImpl 时立即创建 IUserService bean 导致的循环依赖问题。
在 Spring 中,@Lazy 注解用于指定 bean 是否应该在需要时被延迟初始化。当一个 bean 被标记为 @Lazy 时,它的初始化会被推迟到第一次被注入或使用时。
通过将 @Lazy 注解应用于循环依赖链中的一个 bean,可以打破循环依赖,使得 Spring 能够成功初始化这些 bean。
解决Spring循环依赖的一般原则之一,即延迟初始化。