Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Requested bean is currently in creation

Tags:

java

spring

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?

like image 443
JONKI Avatar asked Apr 05 '18 00:04

JONKI


1 Answers

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:

AuthorizationServiceImplUserSearchServiceImplAuthorizationServiceImpl

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:

UserSearchServiceImplAuthorizationServiceImpl

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).

like image 176
Justin Albano Avatar answered Oct 26 '22 23:10

Justin Albano