代码之家  ›  专栏  ›  技术社区  ›  Bato

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

  •  1
  • Bato  · 技术社区  · 10 年前

    我需要一些帮助,因为我自己找不到解决方案,谷歌也帮不上忙。 我有一个模块化的spring应用程序,我可以使用SpringBoot从命令行运行它。 我用 gradle war 命令我已经在带有PostgreSQL数据库和JRE 8的服务器上安装了Tomcat 8。我已将war放入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

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

    1 回复  |  直到 10 年前
        1
  •  1
  •   gipinani    10 年前

    配置中的问题是 PersonService 由加载 @ComponentScan Servlet Context .

    那样的话 个人服务 无法在中访问 Application Context 你的 SecurityConfig 已加载。

    豆类 Servlet上下文 可以在中引用bean 应用程序上下文 ,但反之亦然!

    所以把 @组件扫描 在里面 安全配置 允许该组件可访问。