【发布时间】:2016-08-17 10:59:33
【问题描述】:
我正在使用 Spring Boot 1.4.0,并且在编译代码时遇到循环依赖异常。我的项目结构是标准的,并且结构相同的项目使用 Spring Boot 1.3.5 运行良好。我希望找到一种方法来消除循环依赖异常。
项目 Gradle 文件
dependencies {
compile('org.springframework.boot:spring-boot-starter-security')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-data-mongodb')
compile('org.springframework.boot:spring-boot-starter-data-rest')
compile('org.springframework.boot:spring-boot-starter-actuator')
compile('org.springframework.hateoas:spring-hateoas')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
我的项目结构遵循标准的 MVC 模式,从下到上依次为 MongoDB、Repository、Service、Controller、UserDetailsService 和 Spring Security Configuration。
如下:
存储库
@Repository
public interface LrqaPersonRepository extends MongoRepository<LrqaPerson, String> {
public LrqaPerson findByEmail(String email);
public List<LrqaPerson> findByCountry(String country);
}
服务
@Autowired
public LrqaPersonService(LrqaPersonRepository lrqaPersonRepository,
PasswordEncoder encoder){
this.lrqaPersonRepository = lrqaPersonRepository;
this.encoder = encoder;
}
public LrqaPerson findSingleLrqaPerson(String id){
logger.info("LrqaPersonService method findSingleLrqaPerson() invoked: " + LocalDateTime.now());
LrqaPerson lrqaPerson = this.lrqaPersonRepository.findOne(id);
return lrqaPerson;
}
用户详细信息服务
@Service("personDetailsService")
public class PersonDetailsService implements UserDetailsService {
private static final Logger logger = LoggerFactory.getLogger(PersonDetailsService.class);
private List<GrantedAuthority> auth;
@Autowired
LrqaPersonService personService;
@Override
public UserDetails loadUserByUsername(String email)
throws UsernameNotFoundException {
logger.info("LrqaPersonDetailsService loadUserByUsername() invoked: " + LocalDateTime.now());
LrqaPerson person = personService.findLrqaPersonByEmail(email);
if (person == null) {
throw new UsernameNotFoundException("Invalid Email Username");
}
if (person.getAuthority().equals("user")) {
logger.info("LrqaPersonDetailsService authority privilege detected: " + person.getAuthority());
auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_USER");
}
if (person.getAuthority().equals("admin")) {
logger.info("LrqaPersonDetailsService authority privilege detected: " + person.getAuthority());
auth = AuthorityUtils.commaSeparatedStringToAuthorityList("ROLE_ADMIN, ROLE_USER");
}
return new org.springframework.security.core.userdetails.User(
email, person.getPassword(), auth);
}
}
控制器
@RestController
public class PeopleController {
private final LrqaPersonService personService;
private static final Logger logger = LoggerFactory.getLogger(PeopleController.class);
@Autowired
public PeopleController(LrqaPersonService personService){
this.personService = personService;
}
@RequestMapping(value = "/allpeople", method = RequestMethod.GET)
public List<LrqaPerson> getAllLrqaPeople(){
logger.info("LrqaGenericController method getAllLrqaPeople() invoked: " + LocalDateTime.now());
List<LrqaPerson> lrqaPeople = this.personService.findAllLrqaPersons();
return lrqaPeople;
}
我在运行 ./gradlew bootRun --debug 时遇到的异常是:
例外
11:12:36.141 [QUIET] [system.out] ***************************
11:12:36.141 [QUIET] [system.out] APPLICATION FAILED TO START
11:12:36.141 [QUIET] [system.out] ***************************
11:12:36.141 [QUIET] [system.out]
11:12:36.141 [QUIET] [system.out] Description:
11:12:36.142 [QUIET] [system.out]
11:12:36.142 [QUIET] [system.out] There is a circular dependency between 4 beans in the application context:
11:12:36.142 [QUIET] [system.out] - peopleController defined in file [/Users/frank***/Development/IntelliJ/springAngularJSTutorial/build/classes/main /org/frank/***/controller/PeopleController.class]
11:12:36.142 [QUIET] [system.out] - lrqaPersonService defined in file [/Users/frank***/Development/IntelliJ/springAngularJSTutorial/build/classes/main/org/frank/***/service/LrqaPersonService.class]
11:12:36.142 [QUIET] [system.out] - securityConfig
11:12:36.142 [QUIET] [system.out] - personDetailsService (field org.frank.***.service.LrqaPersonService org.frank.***.security.PersonDetailsService.personService)
11:12:36.142 [QUIET] [system.out] - lrqaPersonService
11:12:36.142 [QUIET] [system.out]
11:12:36.142 [QUIET] [system.out]
11:12:36.180 [DEBUG] [org.gradle.process.internal.DefaultExecHandle] Changing state to: FAILED
我的安全配置如下:
@Configuration
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Resource(name = "personDetailsService")
private PersonDetailsService personDetailsService;
@Autowired
public void configureAuth(AuthenticationManagerBuilder auth)
throws Exception {
auth.inMemoryAuthentication()
.withUser("****").password("****").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers("/user", "/index.html", "/home.html", "/login.html", "/").permitAll()
.anyRequest().authenticated().and()
.formLogin().and()
.httpBasic().and()
.csrf()
.csrfTokenRepository(CookieCsrfTokenRepository.withHttpOnlyFalse());
;
}
@Bean
public PasswordEncoder passwordEncoder() {
PasswordEncoder encoder = new BCryptPasswordEncoder();
return encoder;
}
@Override
protected void configure(AuthenticationManagerBuilder builder) throws Exception { builder.userDetailsService(personDetailsService).passwordEncoder(passwordEncoder());
}
}
我注意到各种在线论坛上对该问题的一些报道。如果有一个循环依赖异常的解决方案,并且我可以在任何地方找到关于为什么 Boot 1.3.5 应用程序结构不生成异常的解释,这对我来说将是一个很大的帮助。也就是说,在 1.3.5 和 1.4.0 之间发生了什么变化。关于这个[如果有适合这个问题的简单描述]。
【问题讨论】:
标签: spring spring-boot