2012-05-29 52 views
1

試圖讓一些實驗用Spring MVC和春季安全:@Service實例化兩次

@Controller 
@RequestMapping("/auth") 
public class AuthController { 
    @Autowired 
    // @Qualifier("userDetailsService") - tried adding this 
    private MyUserDetailsService userDetailsService; 
    ... 
} 

// @Scope("singleton") - tried adding this 
@Service("userDetailsService") 
public class MyUserDetailsService implements UserDetailsService { 
    ... 
} 

完全context.xml中,我有:

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

    <!-- ORIGINAL springmvc-servlet.xml --> 
    <mvc:annotation-driven /> 
    <mvc:resources mapping="/static/**" location="/static/" /> 

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

    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> 

    <context:annotation-config /> 
    <context:component-scan base-package="com.xxxxxxxxx" /> 
    <!-- end ORIGINAL springmvc-servlet.xml --> 

    <!-- FROM springmvc-security.xml --> 
    <security:global-method-security secured-annotations="enabled"> 
    </security:global-method-security> 

    <security:http auto-config="true" access-denied-page="/auth/denied"> 
     <security:intercept-url pattern="/admin/*" access="ROLE_ADMIN"/>   
     <security:intercept-url pattern="/user/*" access="ROLE_USER"/> 
     <security:intercept-url pattern="/auth/login" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:intercept-url pattern="/auth/register" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:intercept-url pattern="/**" access="IS_AUTHENTICATED_ANONYMOUSLY"/> 
     <security:form-login login-page="/auth/login" authentication-failure-url="/auth/login?login_error=true" default-target-url="/user"/> 
     <security:logout logout-url="/auth/logout" logout-success-url="/" invalidate-session="true"/> 
     <security:openid-login authentication-failure-url="/login?login_error=t" user-service-ref="openIdUserDetailsService" /> 
    </security:http> 

    <security:authentication-manager> 
     <security:authentication-provider user-service-ref="userDetailsService" /> 
    </security:authentication-manager> 
    <!-- end FROM springmvc-security.xml -->  
</beans> 

出於某種原因,也有2個實例創建了MyUserDetailsService。第一個被Spring Security使用,第二個被注入到AuthController。如果我想要一個MyUserDetailsService的實例,那麼正確的方法是什麼?

+0

有趣,我總是在想如何讓春天的安全運行與其他豆單應用程序上下文 - 我想他們在不同的人運行。 –

+0

Btw在我當前的配置中UserDetailsS​​ervice僅在SecurityContext中聲明,不在ApplicationContext中(autoscan已禁用)。 –

回答

1

您沒有足夠的配置來確定,但我敢打賭,您對Spring ApplicationContexts應該如何在Spring MVC應用程序中進行管理感到困惑。我的回答對同一個問題的另一個問題是,幾乎可以肯定,你需要閱讀的內容:

Declaring Spring Bean in Parent Context vs Child Context

你最有可能宣佈你的服務的bean(無論是明示或與組件掃描),同時在根和你的應用程序的子上下文。作爲一個服務bean,它應該只存在於根環境中。您還可以受益於閱讀這樣的回答:

Spring XML file configuration hierarchy help/explanation

+0

我已經用我的完整上下文配置更新了這個問題。你可以檢查一下嗎? – agibalov

+0

這是屬於您的DispatcherServlet的上下文文件。你的web.xml中應該有一個名爲「springmvc」的文件。同時顯示你的根上下文是如何初始化的。這可能也是在你的web.xml,ContextLoaderListener和contextConfigLocation參數中完成的。 –

+0

我花了大約一個小時,但現在我明白了。謝謝您的回答 :-) – agibalov

0

此配置爲我的作品:

<security:authentication-manager> 
<security:authentication-provider user-service-ref="userService"> 

<bean id="userService" class="com.mydomain.service.UserDetailsServiceImpl" /> 

A tutorial here

+0

這不會阻止其中的兩個被創建。它只是要更改一個或兩個創建的bean的名稱。 –

+0

@NimChimpsky:重命名爲'theUserDetailsS​​ervice',它仍然是一樣的。 – agibalov

+0

@ loki2302哦,你在應用程序cotnext中更改它?你在其他地方實施userdetailsservice嗎? – NimChimpsky