2012-12-20 64 views
0

編輯:我剛剛意識到問題並不是來自spring-security無法實例化在spring-security.xml文件中引用的userDetailsS​​erviceImpl,而是addUserFormController無法實例化,因爲它無法自動調用UserDetailsS​​erviceImpl。所以這個問題來自於這個控制器無論何種原因都無法到達這個服務bean的UserDetailsS​​erviceImpl。我想我只是通過掃描mvc-dispatcher-servlet.xml中的控制器以及除applicationContext中的控制器之外的所有其他控制器來掃描組件掃描。Spring Security無法在服務層訪問自定義的userDetailsS​​ervice Bean

我正在使用Spring MVC和Hibernate,我試圖將Spring Security與自定義UserDetailsS​​ervice和彙編程序集成。

看起來我的spring security無法訪問應該由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) 

這裏是我的彈簧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> 

這裏是我的web.xml:

<web-app id="WebApp_ID" version="2.4" 
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 

    <display-name>Spring MVC Application</display-name> 

    <!-- Spring MVC --> 
    <servlet> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
     <load-on-startup>1</load-on-startup> 
    </servlet> 

    <servlet-mapping> 
     <servlet-name>mvc-dispatcher</servlet-name> 
     <url-pattern>/</url-pattern> 
    </servlet-mapping> 

    <!-- This listener creates the root application Context --> 
    <listener> 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener> 
    <listener> 
     <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> 
    </listener> 

    <context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/applicationContext.xml, 
      /WEB-INF/spring-security.xml 
     </param-value> 
    </context-param> 

    <!-- Spring Security --> 
    <filter> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class> 
    </filter> 

    <filter-mapping> 
     <filter-name>springSecurityFilterChain</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

</web-app> 

這是我的applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
      http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
      http://www.springframework.org/schema/tx 
      http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 
      http://www.springframework.org/schema/context 
      http://www.springframework.org/schema/context/spring-context-3.0.xsd"> 

<context:annotation-config/> 
<!-- Load everything except @Controllers --> 
<context:component-scan base-package="com"> 
    <context:exclude-filter expression="org.springframework.stereotype.Controller" 
     type="annotation" /> 
</context:component-scan> 

<bean id="transactionManager" 
    class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<bean id="sessionFactory" 
    class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource" /> 
    <!-- <property name="packagesToScan"> 
     <list> 
      <value>com.service</value> 
      <value>com.dao</value> 
     </list> 
    </property> --> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> 
      <prop key="hibernate.hbm2ddl.auto">update</prop> 
      <prop key="hibernate.show_sql">true</prop> 
     </props> 
    </property> 
</bean> 

<bean id="dataSource" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="com.mysql.jdbc.Driver" /> 
    <property name="url" value="jdbc:mysql://localhost:3306/tutospringsource" /> 
    <property name="username" value="root" /> 
    <property name="password" value="password" /> 
</bean> 

<bean 
    class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
    <property name="prefix"> 
     <value>/WEB-INF/pages/</value> 
    </property> 
    <property name="suffix"> 
     <value>.jsp</value> 
    </property> 
</bean> 

<bean id="messageSource" 
    class="org.springframework.context.support.ResourceBundleMessageSource"> 
    <property name="basenames"> 
     <list> 
      <value>mymessages</value> 
     </list> 
    </property> 
</bean> 

<bean id="propertyConfigurer" 
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>classpath:jdbc.properties</value> 
     </list> 
    </property> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager" /> 

<tx:advice id="txAdvice"> 
    <tx:attributes> 
     <tx:method name="save*" /> 
     <tx:method name="*" read-only="false" /> 
    </tx:attributes> 
</tx:advice> 

最後,我的MVC-調度-servlet.xml中:

<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:mvc="http://www.springframework.org/schema/mvc" 
    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/mvc 
     http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> 

    <context:annotation-config /> 

    <context:property-placeholder location="classpath:hibernate.properties" /> 

    <!-- Load @Controllers only --> 
    <context:component-scan base-package="com.controller" 
     use-default-filters="false"> 
     <context:include-filter expression="org.springframework.stereotype.Controller" 
      type="annotation" /> 
    </context:component-scan> 
</beans> 

我AddUserFormController:

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

public class AddUserFormController { 

    private UserDetailsServiceImpl userDetailsService; 

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

我UserDetailsS​​erviceImpl:

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

    @Autowired 
    private UserEntityDAO dao; 

    @Autowired 
    private Assembler assembler; 
+0

看來你聲明它是在包com.service中,但是在包的缺失定義中。 – coderLMN

+0

@Jinzhao Wu - 這個包沒有丟失,我只是沒有粘貼在我的帖子中。我編輯了我的初始文章以反映這一點。 – dukable

+0

你確定'userDetailsS​​ervice'是從spring容器中立即執行嗎?如果你看到你的異常它不能找到'userDetailsS​​ervice'的實例。所以,在服務器啓動的時候在控制檯中看到,你可以看到所有的bean都被創建了。 – SRy

回答

0

我已經能夠解決這個問題。

在我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從模子直接的屬性,最重要的是,我將userDetailsS​​ervice的類型更改爲UserDetailsS​​ervice,而不是UserDetailsS​​erviceImpl。

相關問題