Home > front end >  Spring circular references prohibited in 2.6 version
Spring circular references prohibited in 2.6 version

Time:02-07

I have an issue for circular reference calling. Even if I set true to this option, I cannot fix my issue. How can I fix it? Here are my code snippets which are shown below step by step.

Here is my application.properties file shown below.

...
spring.main.allow-circular-references= true
...

Here is my error message shown below.

Description:

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

   userController (field com.photoapp.users.service.UserService com.photoapp.users.controller.UserController.userService)
┌─────┐
|  userServiceImpl defined in file [C:\Users\de\Desktop\sts-4.9.0.RELEASE\workspace\PhotoAppApiUsers\target\classes\com\photoapp\users\service\impl\UserServiceImpl.class]
↑     ↓
|  webSecurity defined in file [C:\Users\de\Desktop\sts-4.9.0.RELEASE\workspace\PhotoAppApiUsers\target\classes\com\photoapp\users\security\WebSecurity.class]
└─────┘


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.

Here is my userServiceImpl class

@Service
@Transactional
public class UserServiceImpl implements UserService{

    UserMapper userMapper;
    
    UserRepository userRepository;
    
    PasswordEncoder passwordEncoder;
    
    @Autowired
    public UserServiceImpl(UserMapper userMapper,UserRepository userRepository,PasswordEncoder passwordEncoder) {
        super();
        this.userMapper = userMapper;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }


    @Override
    public UserDto createUser(UserDto userDetails) {
        // TODO Auto-generated method stub
        
        userDetails.setUserId(UUID.randomUUID().toString());
        
        User user = userMapper.userDtotoUser(userDetails);
        
        
        String encodedPassword = passwordEncoder.encode(userDetails.getPassword());
        user.setEncryptedPassword(encodedPassword);
        
        userRepository.save(user);
        
        UserDto returnValue = userMapper.userToUserDto(user);
 
        return returnValue;
        
    }


    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        // TODO Auto-generated method stub
        User user = userRepository.findByEmail(username);
        
        if(user == null) 
            throw new UsernameNotFoundException(username);  
        
        return new org.springframework.security.core.userdetails.User(user.getEmail(), 
                user.getEncryptedPassword(), 
                true, true, true, true, new ArrayList<>());
    }
    
    @Override
    public UserDto getUserDetailsByEmail(String email) { 
        User user = userRepository.findByEmail(email);
        
        if(user == null) 
            throw new UsernameNotFoundException(email);
        
        UserDto returnValue = userMapper.userToUserDto(user);
        
        return returnValue;
    }


    @Override
    public UserDto getUserByUserId(String userId) {
        // TODO Auto-generated method stub
        return null;
    }

}

Here is my WebSecurity class

@Configuration
@EnableWebSecurity
public class WebSecurity extends WebSecurityConfigurerAdapter {

    
    private Environment environment;
    private UserService userService;
    
    @Autowired
    public WebSecurity(Environment environment, UserService userService) {
        super();
        this.environment = environment;
        this.userService = userService;
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // TODO Auto-generated method stub
        http.csrf().disable();
        http.authorizeRequests().antMatchers("/users").hasIpAddress(environment.getProperty("gateway.ip"))
        .and()
        .addFilter(getAuthenticationFilter());
        http.headers().frameOptions().disable();
    }

    private AuthenticationFilter getAuthenticationFilter() throws Exception{
        AuthenticationFilter authenticationFilter = new AuthenticationFilter(userService, environment, authenticationManager());
        //authenticationFilter.setAuthenticationManager(authenticationManager()); 
        authenticationFilter.setFilterProcessesUrl(environment.getProperty("login.url.path"));
        return authenticationFilter;
    }
    
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(passwordEncoder());
    }
}

CodePudding user response:

Try using @Lazy

public class WebSecurity extends WebSecurityConfigurerAdapter {

    
    private Environment environment;
    @Lazy
    private UserService userService;

Reference: https://www.baeldung.com/spring-lazy-annotation

CodePudding user response:

The error message is pretty clear. UserServiceImpl depends on WebSecurity which depends on UserServiceImpl.

The dependency from WebSecurity to UserServiceImpl is necessary. That means you need to break the dependency from UserServiceImpl to WebSecurity. This is caused by the password encoder. You need to move that out of WebSecurity. Maybe you can integrate it in UserServiceImpl?

CodePudding user response:

Here is my solution

public UserServiceImpl(UserMapper userMapper,UserRepository userRepository,@Lazy PasswordEncoder passwordEncoder) {
        super();
        this.userMapper = userMapper;
        this.userRepository = userRepository;
        this.passwordEncoder = passwordEncoder;
    }
  •  Tags:  
  • Related