I need some help as I can not find the solution myself and google does not help either. I have a modular spring app, which I can run from command line using SpringBoot with no problem. I've created a war using gradle war
command. I've installed Tomcat 8 on a server with PostgreSQL database and JRE 8. I've put the war into the webapps folder and my external conf files into the conf folder. All my other modules are present in the libs folder of the war file. When I run the Tomcat, I get the following error:
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)}
Here is part of my main conf file:
@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;
The security configuration that defines the 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;
}
A part of the PersonDetailsService class:
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 interface is in package eu.bato.anyoffice.serviceapi.service
and its implementation is in eu.bato.anyoffice.backend.service.impl
and has tags @Service
and @Transactional
I would be very grateful for any hints. I can provide any further logs and information.
The problem in your configuration is that PersonService
is loaded by @ComponentScan
declared in the Servlet Context
.
In that way PersonService
is not accessible in the Application Context
where your SecurityConfig
is loaded.
Beans in Servlet Context
can reference beans in Application Context
, but not vice versa!
So putting @ComponentScan
in SecurityConfig
allow that component to be reacheable.
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.