Reference taken from here (My code exactly same as this repo)- https://github.com/DamianMielcarek/CRM/tree/master/src/main/java/crm
Error
org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'securityConfig': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:410) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.resolveBeanReference(ConfigurationClassEnhancer.java:362) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:334) ~[spring-context-5.3.18.jar:5.3.18]
at com.SecurityConfig$$EnhancerBySpringCGLIB$$4ce77a01.customUserDetailsService(<generated>) ~[classes/:na]
at com.SecurityConfig.configureGlobal(SecurityConfig.java:31) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:724) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1431) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:619) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:953) ~[spring-beans-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.18.jar:5.3.18]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.6.jar:2.6.6]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.6.jar:2.6.6]
at com..BenimcarsApplication.main(BenimcarsApplication.java:16) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.6.6.jar:2.6.6]
SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Bean
public BCryptPasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
@Bean
public SpringDataUserDetailsService customUserDetailsService() {
return new SpringDataUserDetailsService();
}
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(customUserDetailsService()).passwordEncoder(passwordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/admin/**", "/user/delete/**").hasRole("ADMIN")
.antMatchers("/pdf-generator", "/search/**", "/customer/**", "/user/edit/**", "/user/list", "/contract/**").hasAnyRole( "ADMIN", "USER", "MANAGER", "OWNER")
.anyRequest().permitAll()
.and()
.formLogin().loginPage("/login").permitAll()
.and()
.logout().logoutSuccessUrl("/").permitAll()
.and()
.exceptionHandling().accessDeniedPage("/403");
}
}
UserService.java
public interface UserService {
User findByUsername(String username);
Iterable<User> listAllUsers();
User showUser(Long id);
void saveUser(User user);
void editUser(User user);
void deleteUser(User user);
}
UserServiceImpl.java
@Service
public class UserServiceImpl implements UserService {
private UserRepository userRepository;
private RoleRepository roleRepository;
private BCryptPasswordEncoder passwordEncoder;
private AuthenticationManager authenticationManager;
private SpringDataUserDetailsService springDataUserDetailsService;
@Autowired
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
@Autowired
public void setRoleRepository(RoleRepository roleRepository) {
this.roleRepository = roleRepository;
}
@Autowired
public void setPasswordEncoder(BCryptPasswordEncoder passwordEncoder) {
this.passwordEncoder = passwordEncoder;
}
@Autowired
public void setAuthenticationManager(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
}
@Autowired
public void setSpringDataUserDetailsService(SpringDataUserDetailsService springDataUserDetailsService) {
this.springDataUserDetailsService = springDataUserDetailsService;
}
@Override
public User findByUsername(String username) {
return userRepository.findByUsername(username);
}
@Override
public Iterable<User> listAllUsers() {
return userRepository.findAllByEnabled(1);
}
@Override
public User showUser(Long id) {
return userRepository.findOne(id);
}
@Override
public void saveUser(User user) {
Role userRole = roleRepository.findByName("ROLE_USER");
user.setRole(userRole);
user.setEnabled(1);
String password = user.getPassword();
user.setPassword(passwordEncoder.encode(password));
userRepository.save(user);
if (user.getId().equals(1L)) {
userRole = roleRepository.findByName("ROLE_ADMIN");
user.setRole(userRole);
userRepository.save(user);
}
UserDetails userDetails = springDataUserDetailsService.loadUserByUsername(user.getUsername());
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken =
new UsernamePasswordAuthenticationToken(userDetails, password, userDetails.getAuthorities());
authenticationManager.authenticate(usernamePasswordAuthenticationToken);
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
@Override
public void editUser(User user) {
String password = user.getPassword();
user.setPassword(passwordEncoder.encode(password));
Role userRole = roleRepository.findByName("ROLE_USER");
try {
userRole = roleRepository.findById(user.getRole().getId()).orElse(null);;
} catch (NullPointerException e) {
userRole = roleRepository.findByName("ROLE_USER");
} finally {
user.setRole(userRole);
user.setEnabled(1);
userRepository.save(user);
}
}
@Override
public void deleteUser(User user) {
user.setEnabled(0);
user.setPassword(null);
userRepository.save(user);
}
}
SpringDataUserDetailsService.java
@Service
public class SpringDataUserDetailsService implements UserDetailsService {
@Autowired
UserService userService;
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userService.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException(username);
}
String role = user.getRole().getName();
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
grantedAuthorities.add(new SimpleGrantedAuthority(role));
CurrentUser currentUser = new CurrentUser();
currentUser.setUser(user);
currentUser.setAuthorities(grantedAuthorities);
return currentUser;
}
}
CodePudding user response:
UserServiceImpl class needs the object of SpringDataUserDetailsService and SpringDataUserDetailsService class needs the object of UserService which creates the circular dependency. So you have to use @Lazy annotation
@Autowired
public void setSpringDataUserDetailsService(@Lazy SpringDataUserDetailsService springDataUserDetailsService) {
this.springDataUserDetailsService = springDataUserDetailsService;
}
or you can use the @PostContructor annotation
@Service
public class SpringDataUserDetailsService implements UserDetailsService {
@Autowired
UserService userService;
@PostConstruct
public void init() {
userService.setSpringDataUserDetailsService(this);
}
public UserService getUserService() {
return userService;
}
}
@Service
public class UserServiceImpl implements UserService {
private SpringDataUserDetailsService springDataUserDetailsService;
public void setSpringDataUserDetailsService(SpringDataUserDetailsService springDataUserDetailsService) {
this.springDataUserDetailsService = springDataUserDetailsService;
}
}
use this reference https://www.baeldung.com/circular-dependencies-in-spring
CodePudding user response:
The project you're referring to uses Spring Boot 1.5.10. If you're trying to use Spring Boot 2.6.0 or higher, you'll need to either resolve the circular references as mentioned by others, or set spring.main.allow-circular-references
to true
.
See the Spring Boot 2.6 release notes for more information.