Spring Security circular bean dependency

后端 未结 5 1332
梦毁少年i
梦毁少年i 2020-12-13 14:25

I\'m currently working on a Vaadin spring application. According to the app specifications, authentication/authorization of the users must be completed by querying database

相关标签:
5条回答
  • 2020-12-13 14:26

    One of the solution is don't use constructor. For exaple instead of:

    private final JdbcTemplate jdbcTemplate;
    private final PasswordEncoder passwordEncoder;
    
    @Autowired
    public JdbcAccountRepository(JdbcTemplate jdbcTemplate, PasswordEncoder passwordEncoder) {
        this.jdbcTemplate = jdbcTemplate;
        this.passwordEncoder = passwordEncoder;
    }
    

    You can use:

    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    0 讨论(0)
  • 2020-12-13 14:27

    I also faced same problem today. I used @Lazy in the constructor of one class and it solved my problem:

    lang-java 
    
    public class AService {  
        private BService b;   
        public ApplicantService( @NonNull @Lazy BService b){    
            this.b=b;  
            }
       }  
    
    public class BService {  
        private AService a;   
        public ApplicantService( @NonNull  BService a){     
            this.a=a;  
            }
       } 
    
    0 讨论(0)
  • 2020-12-13 14:30

    I prefer the @Lazy method. That way I can stick to one pattern.

    See http://www.baeldung.com/circular-dependencies-in-spring

    0 讨论(0)
  • 2020-12-13 14:42

    Your PasswordEncoder bean definition is in WebSecurityConfig which needs JdbcUserDetailsServices. JdbcUserDetailsServices again is dependent on JdbcAccountRepository which needs PasswordEncoder. So the cycle forms. A simple solution is to take out the PasswordEncoder bean definition out of WebSecurityConfig. Even inside SecurityConfiguration class will solve the cyclic problem.

    0 讨论(0)
  • 2020-12-13 14:52

    You could replace constructor-based dependency injection with setter-based dependency injection to resolve the cycle, see Spring Framework Reference Documentation:

    Circular dependencies

    If you use predominantly constructor injection, it is possible to create an unresolvable circular dependency scenario.

    For example: Class A requires an instance of class B through constructor injection, and class B requires an instance of class A through constructor injection. If you configure beans for classes A and B to be injected into each other, the Spring IoC container detects this circular reference at runtime, and throws a BeanCurrentlyInCreationException.

    One possible solution is to edit the source code of some classes to be configured by setters rather than constructors. Alternatively, avoid constructor injection and use setter injection only. In other words, although it is not recommended, you can configure circular dependencies with setter injection.

    Unlike the typical case (with no circular dependencies), a circular dependency between bean A and bean B forces one of the beans to be injected into the other prior to being fully initialized itself (a classic chicken/egg scenario).

    0 讨论(0)
提交回复
热议问题