Spring Security无法访问服务层中的自定义userDetailsService Bean

Spring Security无法访问服务层中的自定义userDetailsService Bean,spring,spring-mvc,spring-security,Spring,Spring Mvc,Spring Security,编辑:我刚刚意识到问题不是来自spring security无法实例化spring-security.xml文件中引用的userDetailsServiceImpl,而是无法实例化的addUserFormController,因为它无法自动连接userDetailsServiceImpl。因此,问题来自这样一个事实:无论出于何种原因,该控制器都无法访问该服务bean UserDetailsServiceImpl。我想我已经正确地进行了组件扫描,只扫描了mvc-dispatcher-servlet

编辑:我刚刚意识到问题不是来自spring security无法实例化spring-security.xml文件中引用的userDetailsServiceImpl,而是无法实例化的addUserFormController,因为它无法自动连接userDetailsServiceImpl。因此,问题来自这样一个事实:无论出于何种原因,该控制器都无法访问该服务bean UserDetailsServiceImpl。我想我已经正确地进行了组件扫描,只扫描了mvc-dispatcher-servlet.xml中的控制器,以及applicationContext中除控制器之外的所有其他控制器。

我正在使用SpringMVC和Hibernate,并试图将SpringSecurity与自定义UserDetailsService和汇编程序集成

看起来我的spring安全性无法访问applicationContext.xml应该扫描的bean

加载应用程序时,我遇到以下错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'addUserFormController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void com.controller.AddUserFormController.setUserDetailsService(com.service.UserDetailsServiceImpl); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.service.UserDetailsServiceImpl] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {}
    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
以下是我的spring-security.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
    xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context-3.0.xsd
                        http://www.springframework.org/schema/security 
                        http://www.springframework.org/schema/security/spring-security-3.1.xsd">

    <http auto-config='true' use-expressions='true'>
        <intercept-url pattern="/login*" access="isAnonymous()" />
        <intercept-url pattern="/secure/**" access="hasRole('ROLE_Admin')" />

        <logout logout-success-url="/listing.htm" />

        <form-login login-page="/login.htm" login-processing-url="/j_spring_security_check"
            authentication-failure-url="/login_error.htm" default-target-url="/listing.htm"
            always-use-default-target="true" />
    </http>

    <beans:bean id="com.daoAuthenticationProvider"
        class="org.springframework.security.authentication.dao.DaoAuthenticationProvider">
        <beans:property name="userDetailsService" ref="userDetailsService" />
    </beans:bean>

    <beans:bean id="authenticationManager"
        class="org.springframework.security.authentication.ProviderManager">
        <beans:property name="providers">
            <beans:list>
                <beans:ref local="com.daoAuthenticationProvider" />
            </beans:list>
        </beans:property>
    </beans:bean>

    <authentication-manager>
        <authentication-provider user-service-ref="userDetailsService">
            <password-encoder hash="plaintext" />
        </authentication-provider>
    </authentication-manager>

</beans:beans>
我的UserDetailsServiceImpl:

package com.service;
@Service("userDetailsService")
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserEntityDAO dao;

    @Autowired
    private Assembler assembler;

我已经解决了这个问题

在我的AddUserFormController中,我有:

@Controller
@RequestMapping("/register.htm")

public class AddUserFormController {

private UserDetailsService userDetailsService;


    @Autowired
    public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
下面是它现在的样子:

@Controller
@RequestMapping("/register.htm")
public class AddUserFormController {

    @Autowired
    private UserDetailsService userDetailsService;

    public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }

我将@Autowired从setter直接移动到属性,最重要的是,我将userDetailsService的类型更改为userDetailsService,而不是UserDetailsServiceImpl。

您似乎在package com.service中声明了它,但在定义中包丢失了。@Jinzhao Wu-包没有丢失,我只是没有把它贴在我的帖子里。我编辑了我的第一篇文章来反映这一点。你确定
userDetailsService
是从spring容器实例化的吗?如果你看到异常,它将无法找到
userDetailsService
的实例。因此,在控制台中,当服务器启动时,您可以看到所有bean都创建了什么。@Jinzhao Wu-是的,包声明在AddUserFormController:package com.controller中;是这样吗?
@Controller
@RequestMapping("/register.htm")

public class AddUserFormController {

    private UserDetailsServiceImpl userDetailsService;

    @Autowired
    public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
package com.service;
@Service("userDetailsService")
@Transactional
public class UserDetailsServiceImpl implements UserDetailsService {

    @Autowired
    private UserEntityDAO dao;

    @Autowired
    private Assembler assembler;
@Controller
@RequestMapping("/register.htm")

public class AddUserFormController {

private UserDetailsService userDetailsService;


    @Autowired
    public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }
@Controller
@RequestMapping("/register.htm")
public class AddUserFormController {

    @Autowired
    private UserDetailsService userDetailsService;

    public void setUserDetailsService(UserDetailsServiceImpl userDetailsService) {
        this.userDetailsService = userDetailsService;
    }