简体   繁体   中英

No qualifying bean of type 'xxx.xxx.xxx.xxx.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate

I keep getting the above error when trying to implement spring-security. Please kindly help out as i'm fairly new to spring mvc

I have tried using solutions provided on

No qualifying bean of type available in SpringBoot Application

No qualifying bean of type 'concert.PerformanceImp' available

and some others but i couldn't figure out why the issue still persist

My Codes


/** spring security configurer **/

@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    MyUserDetailsService userDetailsService;    


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }


    @Override
    protected void configure (HttpSecurity http) throws Exception {
        http
            .authorizeRequests()
                /**
                 * None of these urls requires authentication and any other urls
                 * not specified here, will require authentication
                 */
                .antMatchers(
                        "/", 
                        "/about", 
                        "/account/create"
                ).permitAll();

        http
            .formLogin()
                .loginPage("/account/login")
                .usernameParameter("email")
                .permitAll()
                .and()
                    .logout()
                    .permitAll();
    }
}



/** Custom UserDetailsService **/
@Service
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private AccountDao accountDao;

    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Account account = accountDao.findAccountByEmail(email);
        System.out.println("User " + account );

        if(account == null ) {
            throw new UsernameNotFoundException(
                    "User " + email + " was not found in database");
        }

        return (UserDetails) account;
    }
}




/** Front Controller **/

@Configuration
@EnableWebMvc

// the package set on component scan is the parent package, and every other packages are within it
// as some suggestions from slackoverflow pointed that it could be that the package of 
// MyUserDetailsService is not seen by the component scan 

@ComponentScan(basePackages= {"com.springmvcproject.concertio"})
public class FrontController implements WebMvcConfigurer {

    @Bean(name="messageSource")
    public MessageSource getMessageSource() {
        ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
        messageSource.setBasename("messages");
        return messageSource;
    }


    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/concertio/resources/**").addResourceLocations("/")
        .setCachePeriod(31556926);
    }


    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        configurer.enable();
    }



    @Bean
    InternalResourceViewResolver viewResolver(){
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setRequestContextAttribute("requestContext");

        return resolver;
    }

}

Server Error Log

Nov 06, 2019 6:01:37 PM org.apache.catalina.core.StandardContext listenerStart
SEVERE: Exception sending context initialized event to listener instance of class [org.springframework.web.context.ContextLoaderListener]
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'securityConfig': Unsatisfied dependency expressed through field 'userDetailsService'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.springmvcproject.concertio.service.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:581)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:91)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:367)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1340)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:502)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:312)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:310)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:756)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:868)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.web.context.ContextLoader.configureAndRefreshWebApplicationContext(ContextLoader.java:409)
    at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:291)
    at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:103)
    at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4666)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5136)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:831)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1377)
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1367)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:140)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:902)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:262)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:423)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:928)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:638)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:350)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.springmvcproject.concertio.service.MyUserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1501)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1099)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1060)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:578)
    ... 45 more

Nov 06, 2019 6:01:37 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: One or more listeners failed to start. Full details will be found in the appropriate container log file
Nov 06, 2019 6:01:37 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/concertio] startup failed due to previous errors
Nov 06, 2019 6:01:37 PM org.apache.catalina.core.ApplicationContext log
INFO: Closing Spring root WebApplicationContext
Nov 06, 2019 6:01:37 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-nio-8080"]
Nov 06, 2019 6:01:37 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-nio-8009"]
Nov 06, 2019 6:01:37 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in [7,536] milliseconds

I have also used the same step followed by the OP here

Spring security Cant autowire UserDetailsService

but the error still persist... Any help will be highly appreciated

Through the help of @PraveenKumarLalasangi, i was able to fix the above error...

This is the current working code base

SecurityConfig


@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserDetailsService userDetailsService;


    @Autowired
    public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userDetailsService);
    }

    .....
    .....
    .....

}

MyUserDetailsService

@Component
public class MyUserDetailsService implements UserDetailsService {

    @Autowired
    private AccountDao accountDao;

    @Transactional(readOnly=true)
    @Override
    public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
        Account account = accountDao.findAccountByEmail(email);
        System.out.println("User " + account );

        if(account == null ) {
            throw new UsernameNotFoundException(
                    "User " + email + " was not found in database");
        }

        return (UserDetails) account;
    }
}

FrontController


@Configuration
@EnableWebMvc
@ComponentScan(basePackages= {"com.springmvcproject.concertio"})
public class FrontController implements WebMvcConfigurer {
     @Bean(name="messageSource")
    public MessageSource getMessageSource() { .....  }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {....}

    @Override
    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { .... }

   @Bean
    InternalResourceViewResolver viewResolver(){ .... }
}

WebConfig

public class WebConfig extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {
            FrontController.class
        };
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
            "/" 
        };
    }

}

I hope someone finds this helpful

Spring uses its configuration to find and construct its context. And as a part of its configuration you specify where (in which package(s)) the bean classes are located. @ComponentScan(basePackages= {"com.springmvcproject.concertio"}) tells Spring are beans are associated with the com.springmvcproject.concertio package or its sub packages. Is the MyUserDetailsService class placed in this package or sub packages?

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM