简体   繁体   中英

The dependencies of some of the beans in the application context form a cycle errors in spring boot

When I run my app, I get the error I shown below that the dependencies of some of the beans in the application context form a cycle. Im not sure where exactly the problem is coming from. Still relatively new to spring boot/spring security so any pointers on my code on would be appreciated.

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

   userController defined in file [/Users/jason/Desktop/Coding/Job-Application-Tracker/target/classes/com/example/jobapplicationtracker/controllers/UserController.class]
┌─────┐
|  userServiceImpl defined in file [/Users/jason/Desktop/Coding/Job-Application-Tracker/target/classes/com/example/jobapplicationtracker/services/UserServiceImpl.class]
↑     ↓
|  securityConfig defined in file [/Users/jason/Desktop/Coding/Job-Application-Tracker/target/classes/com/example/jobapplicationtracker/securities/SecurityConfig.class]
└─────┘

UserServiceImpl

@Service
@RequiredArgsConstructor
@Slf4j
public class UserServiceImpl implements UserService, UserDetailsService {
    @Autowired
    private final UserRepository userRepository;
    @Autowired
    private final PasswordEncoder passwordEncoder;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if(user == null){
            log.error("User not found in the database");
            throw new UsernameNotFoundException("User not found in the database");
        } else {
            log.info("User found in the database: {}", username);
        }
        Collection<SimpleGrantedAuthority> authorities = new ArrayList<>();
        user.getApplications().forEach(application -> authorities.add(new SimpleGrantedAuthority(application.getApplicationId().toString())));
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(), authorities);
    }

    @Override
    public User getUser(String username) {
        log.info("Fetching user {}", username);
        return this.userRepository.findByUsername(username);
    }

    @Override
    public List<User> getUsers() {
        log.info("Fetching all users.");
        return this.userRepository.findAll();
    }

    @Override
    public User saveUser(User user) {
        log.info("User {} is saved to the database", user);
        user.setPassword( passwordEncoder.encode(user.getPassword()));
        return this.userRepository.save(user);
    }

}

SecurityConfig

@EnableWebSecurity
@Configuration
@RequiredArgsConstructor
public class SecurityConfig {
    private final UserDetailsService userDetailsService;
    private final AuthenticationConfiguration authenticationConfiguration;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    @Bean
    AuthenticationManager authenticationManager(AuthenticationManagerBuilder auth) throws Exception {
        return auth.userDetailsService(userDetailsService).passwordEncoder(passwordEncoder()).and().build();
    }

    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.cors().and().csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .authorizeRequests().anyRequest().permitAll();
        http.addFilter(new CustomAuthenticationFilter(authenticationManagerBeans()));
        return http.build();
    }

    @Bean
    public AuthenticationManager authenticationManagerBeans() throws Exception
    {
        return authenticationConfiguration.getAuthenticationManager();
    }

}

Your issue relates to Prohibit circular references by default #27652 , I'm not sure what was the motivation to prohibit circular dependencies by default, however the general recommendation now is "your code is poor - refactor it", on the other hand you may disable this feature via "spring.main.allow-circular-references=true".

In regard to your case:

  • SecurityConfig "initialises" PasswordEncoder and depends on UserDetailsService
  • UserDetailsService depends on PasswordEncoder

so, it is clear that we got a cycle, and the "recommended solution" would be move PasswordEncoder to another configuration class.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM