在Spring Boot中注入自动连接依赖项的问题

时间:2015-06-28 12:10:55

标签: java spring spring-mvc spring-security spring-boot

我在下面的代码中获得@Autowired AccountRepository的NoSuchBeanDefinitionException,并显示错误消息:No qualifying bean of type [com.brahalla.PhotoAlbum.dao.AccountRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency.。我已将包含存储库的包添加到@ComponentScan但由于某种原因它仍然没有看到它。依赖注入在我的项目中的其他任何地方都可以使用,而不是在这个特定的文件中。

package com.brahalla.PhotoAlbum.configuration;

import com.brahalla.PhotoAlbum.dao.AccountRepository;
import com.brahalla.PhotoAlbum.domain.entity.Account;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.authentication.configurers.GlobalAuthenticationConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

@Configuration
@ComponentScan("com.brahalla.PhotoAlbum.dao")
public class GlobalAuthenticationConfiguration extends GlobalAuthenticationConfigurerAdapter {

  @Autowired
  AccountRepository accountRepository;

  @Override
  public void init(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    authenticationManagerBuilder.userDetailsService(userDetailsService());
  }

  @Bean
  UserDetailsService userDetailsService() {
    return new UserDetailsService() {

      @Override
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Account account = accountRepository.findByUsername(username);
        if(account != null) {
          return new User(
            account.getUsername(),
            account.getPassword(),
            true, true, true, true,
            AuthorityUtils.createAuthorityList("USER")
          );
        } else {
          throw new UsernameNotFoundException("could not find the user '" + username + "'");
        }
      }

    };
  }

}

这是存储库:

package com.brahalla.PhotoAlbum.dao;

import com.brahalla.PhotoAlbum.domain.entity.Account;

import org.springframework.data.repository.CrudRepository;

public interface AccountRepository extends CrudRepository<Account, Long> {

  public Account findByUsername(String username);

}

主应用程序配置:

package com.brahalla.PhotoAlbum.configuration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ApplicationConfiguration {

    public static void main(String[] args) {
        SpringApplication.run(ApplicationConfiguration.class, args);
    }

}

这是完整的日志和堆栈跟踪:http://pastebin.com/PKvd8rXV

编辑 Here is the git repository,相关代码位于分支develop

7 个答案:

答案 0 :(得分:3)

带有@ controller,@ service,@ component,@ Repository等注释的类将成为自动接线的候选者,而其他类则不是。因此,请考虑为您的班级进行相应的自动接线注释。

@Component - &gt;任何Spring管理的组件的通用构造型

<强> @Repository - &GT;持久层的构造型

@Service - &gt;服务层的构造型

@Controller - &gt;表示层的构造型(spring-mvc)

以下代码应该可以使用

 @Repository
 public interface AccountRepository extends CrudRepository<Account, Long> {

  public Account findByUsername(String username);
}

答案 1 :(得分:1)

我发现了问题的解决方案,我只想确保将其发布在此处。

首先,我将所有Web配置选项移动到扩展WebSecurityConfigurerAdapter的单个类。其次,我不得不将AuthenticationManagerBuilder初始化的注释更改为@Autowired而不是@Override。第三,我必须公开UserDetailsS​​ervice bean:

package com.brahalla.PhotoAlbum.configuration;

import com.brahalla.PhotoAlbum.dao.AccountRepository;
import com.brahalla.PhotoAlbum.domain.entity.Account;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

@Configuration
@EnableWebSecurity
public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter {

  @Autowired
  AccountRepository accountRepository;

  @Autowired
  public void configureAuthentication(AuthenticationManagerBuilder authenticationManagerBuilder) throws Exception {
    authenticationManagerBuilder
      .userDetailsService(userDetailsService());
  }

  @Override
  protected void configure(HttpSecurity httpSecurity) throws Exception {
    httpSecurity
      .authorizeRequests()
        .anyRequest().fullyAuthenticated()
      //.and().authorizeUrls()
      /*.and().formLogin()
        .loginPage("/login")
        .permitAll()
      .and().logout()
        .permitAll()*/
      .and().httpBasic()
      .and().csrf()
        .disable();
  }

  @Bean
  public UserDetailsService userDetailsService() {
    return new UserDetailsService() {

      @Override
      public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        Account account = accountRepository.findByUsername(username);
        if(account != null) {
          return new User(
            account.getUsername(),
            account.getPassword(),
            true, true, true, true,
            AuthorityUtils.createAuthorityList("USER")
          );
        } else {
          throw new UsernameNotFoundException("could not find the user '" + username + "'");
        }
      }

    };
  }

}

答案 2 :(得分:0)

我认为您在@EnableJpaRepositories课程中遗漏了ApplicationConfiguration

答案 3 :(得分:0)

您可以发布应用程序的调试日志吗?它将了解bean是否已创建。尝试将componentscan放在applicationconfiguration类中,并使用@component或相关注释标记GlobalAuthenticationConfiguration

答案 4 :(得分:0)

您可以尝试使用以下代码段:

package com.brahalla.PhotoAlbum.dao;

import com.brahalla.PhotoAlbum.domain.entity.Account;
import org.springframework.stereotype.Repository;
import org.springframework.data.repository.CrudRepository;

@Repository
public interface AccountRepository extends CrudRepository<Account, Long> {

  public Account findByUsername(String username);

}

另外,使用ApplicationConfiguration

@EnableJpaRepositories添加注释

答案 5 :(得分:0)

1)您是否可以尝试将您的课程ApplicationConfiguration放入根包com.brahalla.PhotoAlbum而不是com.brahalla.PhotoAlbum.configuration

实际上,@SpringBootApplication会扫描它所在位置的子包。

请参阅Reference Guide 14.2 Locating the main application class

2)正如其他人所说,将@EnableJpaRepositories放在你的班级GlobalAuthenticationConfiguration

使用这两种配置,它应该可以工作

答案 6 :(得分:0)

我遇到了同样的问题,这个问题恰恰是由于Spring Boot ApplicationConfiguration.java是在特定包中创建的,而不是在root中创建的。我把它移到root它工作得很好。

但最初是在com.myproject.root.config中,我把它移到了com.myproject.root