我需要一些帮助,因为我自己找不到解决方案,谷歌也没有帮助。
我有一个模块化弹簧应用程序,我可以使用SpringBoot从命令行运行没有问题。
我使用gradle war
命令创建了一场战争。我已经在带有PostgreSQL数据库和JRE 8的服务器上安装了Tomcat 8.我已将战争放入webapps文件夹,将外部conf文件放入conf文件夹。
我所有的其他模块都存在于war文件的libs文件夹中。
当我运行Tomcat时,我收到以下错误:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'securityConfig': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'personDetailsService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private eu.bato.anyoffice.serviceapi.service.PersonService eu.bato.anyoffice.frontend.config.PersonDetailsService.personService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [eu.bato.anyoffice.serviceapi.service.PersonService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
以下是我的主要conf文件的一部分:
@Configuration
@EnableAutoConfiguration
@ComponentScan(value = {"eu.bato.anyoffice"})
@EnableWebMvc
public class Application extends WebMvcConfigurerAdapter{
@Autowired
SchedulerService scheduler;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@PostConstruct
protected void startScheduler(){
scheduler.start();
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/login").setViewName("login");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
}
@Autowired
private MessageSource messageSource;
定义PersonDetailsService bean的安全性配置:
@Configuration
@EnableWebMvcSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
private static final Logger log = LoggerFactory.getLogger(SecurityConfig.class);
@Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(personDetailsService()).passwordEncoder(new StandardPasswordEncoder());
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.addFilterBefore(authenticationFilter(), LogoutFilter.class)
.csrf().disable()
.authorizeRequests()
......
.permitAll();
}
@Bean
PersonDetailsService personDetailsService() {
return new PersonDetailsService();
}
@Bean
Filter authenticationFilter() {
BasicAuthenticationFilter basicAuthFilter = new BasicAuthenticationFilter(customAuthenticationManager(), new BasicAuthenticationEntryPoint());
return basicAuthFilter;
}
@Bean
ProviderManager customAuthenticationManager() {
List<AuthenticationProvider> providers = new LinkedList<>();
providers.add(daoAuthPovider());
ProviderManager authenticationManager = new ProviderManager(providers);
authenticationManager.setEraseCredentialsAfterAuthentication(true);
return authenticationManager;
}
@Bean
DaoAuthenticationProvider daoAuthPovider() {
DaoAuthenticationProvider provider = new DaoAuthenticationProvider();
provider.setUserDetailsService(personDetailsService());
provider.setPasswordEncoder(new StandardPasswordEncoder());
//TODO: add salt
return provider;
}
PersonDetailsService类的一部分:
public class PersonDetailsService implements UserDetailsService {
private static final Logger log = LoggerFactory.getLogger(PersonDetailsService.class);
private static final StandardPasswordEncoder encoder = new StandardPasswordEncoder();
@Autowired
private PersonService personService;
@Autowired
private Environment environment;
@PostConstruct
protected void initialize() {
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
log.info("Authenticating: " + username);
PersonService接口位于包eu.bato.anyoffice.serviceapi.service
中,其实现位于eu.bato.anyoffice.backend.service.impl
,其标记为@Service
和@Transactional
我会非常感谢任何提示。我可以提供任何进一步的日志和信息。
答案 0 :(得分:1)
您的配置中的问题是PersonService
由@ComponentScan
中声明的Servlet Context
加载。
这样PersonService
无法在Application Context
中加载SecurityConfig
。
Servlet Context
中的Bean可以引用Application Context
中的bean,但反之亦然!
将@ComponentScan
放入SecurityConfig
允许该组件可以访问。