没有bean有资格作为此依赖项的autowire候选者

时间:2015-12-30 00:01:33

标签: java spring spring-boot

这是一个Spring Boot问题,因此与其他帖子such as this one不同,后者在不同的上下文中包含相同的错误消息。 如何解决以下错误,使自定义用户详细信息服务能够自动连接到下面显示的spring boot应用程序?

键入mvn spring-boot:run时抛出的错误是:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException:  
No qualifying bean of type [demo.UiApplication$UserRepository] found  
for dependency: expected at least 1 bean which qualifies as autowire  
candidate for this dependency. Dependency annotations: {}  

错误指向的代码中的位置是:

@Repository
interface UserRepository extends CrudRepository<User, Long> {
    User findByName(String name);
}

这个非常简单的测试应用程序的完整代码是:

@SpringBootApplication
@Controller
public class UiApplication extends WebMvcConfigurerAdapter {

// Match everything without a suffix (so not a static resource)
@RequestMapping(value = "/{[path:[^\\.]*}")
public String redirect() {
    // Forward to home page so that route is preserved.
    return "forward:/";
}

@RequestMapping("/user")
@ResponseBody
public Principal user(Principal user) {
    return user;
}   

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

@Bean
public LocaleResolver localeResolver() {
    SessionLocaleResolver slr = new SessionLocaleResolver();
    slr.setDefaultLocale(Locale.US);
    return slr;
}

@Bean
public LocaleChangeInterceptor localeChangeInterceptor() {
    LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
    lci.setParamName("lang");
    return lci;
}

@Override
public void addViewControllers(ViewControllerRegistry registry) {
    registry.addViewController("/login").setViewName("login");
}

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(localeChangeInterceptor());
}

@Bean
public SecurityConfiguration applicationSecurity() {
    return new SecurityConfiguration();
}

@Order(Ordered.HIGHEST_PRECEDENCE)
@Configuration
protected static class AuthenticationSecurity extends
        GlobalAuthenticationConfigurerAdapter {

    @Autowired
    private Users users;

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

@SuppressWarnings("deprecation")
@Configuration
@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
@EnableWebMvcSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
protected static class SecurityConfiguration extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.httpBasic().and().authorizeRequests()
                .antMatchers("/index.html", "/", "/login", "/message", "/home")
                .permitAll().anyRequest().authenticated().and().csrf()
                .csrfTokenRepository(csrfTokenRepository()).and()
                .addFilterAfter(csrfHeaderFilter(), CsrfFilter.class);
    }

    private Filter csrfHeaderFilter() {
        return new OncePerRequestFilter() {
            @Override
            protected void doFilterInternal(HttpServletRequest request,
                    HttpServletResponse response, FilterChain filterChain)
                    throws ServletException, IOException {
                CsrfToken csrf = (CsrfToken) request.getAttribute(CsrfToken.class
                        .getName());
                if (csrf != null) {
                    Cookie cookie = WebUtils.getCookie(request, "XSRF-TOKEN");
                    String token = csrf.getToken();
                    if (cookie == null || token != null
                            && !token.equals(cookie.getValue())) {
                        cookie = new Cookie("XSRF-TOKEN", token);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                    }
                }
                filterChain.doFilter(request, response);
            }
        };
    }

    private CsrfTokenRepository csrfTokenRepository() {
        HttpSessionCsrfTokenRepository repository = new HttpSessionCsrfTokenRepository();
        repository.setHeaderName("X-XSRF-TOKEN");
        return repository;
    }
}

@Service
class Users implements UserDetailsService {

private UserRepository repo;

@Autowired
public Users(UserRepository repo) {
    this.repo = repo;
}

@Override
public UserDetails loadUserByUsername(String username)
        throws UsernameNotFoundException {
    User user = repo.findByName(username);
    if (user == null) {
        return null;
    }
    List<GrantedAuthority> auth = AuthorityUtils
            .commaSeparatedStringToAuthorityList("ROLE_USER");
    if (username.equals("admin")) {
        auth = AuthorityUtils
                .commaSeparatedStringToAuthorityList("ROLE_ADMIN");
    }
    String password = user.getPassword();
    return new org.springframework.security.core.userdetails.User(username, password,
            auth);
}

}

@Controller
@Repository
interface UserRepository extends CrudRepository<User, Long> {
User findByName(String name);
}

@Entity
class User {
@GeneratedValue
@Id
private Long iduser;
private String name;
private String password;
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private Collection<SessionLog> sessionLogCollection;

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}
}

@Entity
class SessionLog {

    @GeneratedValue
    @Id
    private Long id;
    private String sessionid;
    @ManyToOne(optional = true)
    @JoinColumn(name = "iduser")
    private User user;

    public String getSessionid(){
            return sessionid;
    }
}

}

CentOS 7终端的启动日志非常长,但最后一个元素是:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [demo.UiApplication$UserRepository] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1373)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1119)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1014)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 38 more

4 个答案:

答案 0 :(得分:2)

您的UserRepository是嵌套界面,告诉您希望发现该界面

@SpringBootApplication
@Controller
@EnableJpaRepositories(basePackages = "demo", considerNestedRepositories = true)
public class UiApplication extends WebMvcConfigurerAdapter {

请参阅:http://docs.spring.io/spring-data/jpa/docs/1.6.0.RELEASE/api/org/springframework/data/jpa/repository/config/EnableJpaRepositories.html#considerNestedRepositories()

答案 1 :(得分:1)

你错过了

@EnableJpaRepositories("your.package")

...注解

@SpringBootApplication
@Controller
@EnableJpaRepositories("your.package")
public class UiApplication extends WebMvcConfigurerAdapter {
    ....
}

答案 2 :(得分:1)

如果您的Entity类在不同的包中,则需要添加以下注释。看看这个答案可能会有所帮助 link

@EntityScan("Entity.package")
@EnableJpaRepositories("repository.package")

答案 3 :(得分:0)

这意味着您应该提供UserRepository类型的bean。容器在尝试构造(注入)Users时发出消息:查看标有@Autowired的构造函数,容器在您的配置中搜索UserRepository bean,但没有被发现并引发致命错误。

您可以通过在@Configuration类之一中添加提供程序方法来实现此目的:

@Bean
public UserRepository userRepository(DataSource dataSource) {
    return new UserRepositoryImpl(dataSource);
}

或直接用@Service(或任何等效的刻板印象注释)注释所需的类