My controller
@RestController
public class CheckUserDataRestController {
private final UserSearchService userSearchService;
@Autowired
public CheckUserDataRestController(final UserSearchService userSearchService) {
this.userSearchService = userSearchService;
}
...
}
initialize bean service
@Service("userSearchService")
public class UserSearchServiceImpl implements UserSearchService {
private final UserRepository userRepository;
private final AuthorizationService authorizationService;
@Autowired
public UserSearchServiceImpl(
@NotNull final UserRepository userRepository,
@NotNull final AuthorizationService authorizationService
) {
this.userRepository = userRepository;
this.authorizationService = authorizationService;
}
...
}
which initializes another service bean
@Service("authorizationService")
public class AuthorizationServiceImpl implements AuthorizationService {
private final UserSearchService userSearchService;
@Autowired
public AuthorizationServiceImpl(final UserSearchService userSearchService) {
this.userSearchService = userSearchService;
}
...
}
The following error is thrown during compilation:
2018-04-05 02:09:39.024 WARN 1864 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'checkUserDataRestController' defined in file [C:\Users\Jonatan\Documents\GitHub\REST-Web-Services\web\out\production\classes\com\web\web\controller\CheckUserDataRestController.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'userSearchService' defined in file [C:\Users\Jonatan\Documents\GitHub\REST-Web-Services\core\out\production\classes\com\core\jpa\service\UserSearchServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'authorizationService' defined in file [C:\Users\Jonatan\Documents\GitHub\REST-Web-Services\core\out\production\classes\com\core\service\impl\AuthorizationServiceImpl.class]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'userSearchService': Requested bean is currently in creation: Is there an unresolvable circular reference?
The error is caused by the fact that the UserSearchService
service is autowired simultaneously in the controller and in the AuthorizationService
service. How do I prevent this error?
The issue is that the constructor of AuthorizationServiceImpl
requires a bean of UserSearchService
to be wired, which means UserSearchServiceImpl
will be wired, but the constructor of UserSearchServiceImpl
requires a bean of AuthorizationServiceImpl
to be wired (which means that AuthorizationServiceImpl
will be wired). This dependency is circular and Spring cannot resolve it without help on the part of the developer:
AuthorizationServiceImpl
→ UserSearchServiceImpl
→ AuthorizationServiceImpl
One way to break this circular dependency is to inject the UserSearchService
bean into AuthorizationServiceImpl
through setter injection, rather than through constructor injection. This allows Spring to create the AuthorizationServiceImpl
bean without needing to create the UserSearchServiceImpl
bean. Once the AuthorizationServiceImpl
has been initialized, the UserSearchServiceImpl
bean can then be initialized. Once UserSearchServiceImpl
has been initialized, it can be wired into AuthorizationServiceImpl
using its setter. This reduces the dependencies to the following:
UserSearchServiceImpl
→ AuthorizationServiceImpl
To do this, change AuthorizationServiceImpl
to the following:
@Service("authorizationService")
public class AuthorizationServiceImpl implements AuthorizationService {
private UserSearchService userSearchService;
public AuthorizationServiceImpl() {}
@Autowired
public void setUserSearchService(UserSearchService userSearchService) {
this.userSearchService = userSearchService;
}
...
}
and UserSearchServiceImpl
to the following:
@Service("userSearchService")
public class UserSearchServiceImpl implements UserSearchService {
private final UserRepository userRepository;
private AuthorizationService authorizationService;
@Autowired
public UserSearchServiceImpl(@NotNull final UserRepository userRepository) {
this.userRepository = userRepository;
}
@Autowired
public void setAuthorizationService(AuthorizationService authorizationService) {
this.authorizationService = authorizationService;
}
...
}
It is important to note that technique requires that the userSearchService
and authorizationService
fields be made mutable (the final
qualifier is removed).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With