将spring模块化应用程序部署到tomcat后,“Autowire”失败

时间:2015-03-21 23:01:58

标签: java spring tomcat autowired

我需要一些帮助,因为我自己找不到解决方案,谷歌也没有帮助。 我有一个模块化弹簧应用程序,我可以使用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;

定义PersonDetailsS​​ervice 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;
    }

PersonDetailsS​​ervice类的一部分:

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

我会非常感谢任何提示。我可以提供任何进一步的日志和信息。

1 个答案:

答案 0 :(得分:1)

您的配置中的问题是PersonService@ComponentScan中声明的Servlet Context加载。

这样PersonService无法在Application Context中加载SecurityConfig

Servlet Context中的Bean可以引用Application Context中的bean,但反之亦然!

@ComponentScan放入SecurityConfig允许该组件可以访问。