Мне нужна помощь, так как я не могу найти решение самостоятельно, и google тоже не помогает. У меня есть модульное приложение весны, которое я могу запустить из командной строки с помощью SpringBoot без проблем. Я создал войну с помощью команды gradle war
. Я установил Tomcat 8 на сервере с базой данных PostgreSQL и JRE 8. Я поместил войну в папку webapps и мои внешние файлы conf в папку conf. Все мои другие модули присутствуют в папке 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:
@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
Я был бы очень благодарен за любые намеки. Я могу предоставить любые дополнительные журналы и информацию.
Проблема в вашей конфигурации заключается в том, что PersonService
загружается @ComponentScan
объявленным в Servlet Context
@ComponentScan
.
Таким образом, PersonService
недоступен в Application Context
котором загружен ваш SecurityConfig
.
Бобы в Servlet Context
могут ссылаться на beans в Application Context
, но не наоборот!
Таким образом, включение @ComponentScan
в SecurityConfig
позволяет этому компоненту быть повторно доступным.