[SPRING] 스프링 웹, 보안 + web.xml + mvc 디스패처 + Bean이 두 번 생성됨
SPRING스프링 웹, 보안 + web.xml + mvc 디스패처 + Bean이 두 번 생성됨
아래 Web.xml 있습니다.
<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>
<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>/api/secure/*</url-pattern>
</filter-mapping>
[편집하다]
스프링 보안을 추가 한 후에 오류가 발생합니다!
그 때 나는 덧붙였다.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
다음 그것은 잘 작동하는 것,하지만 다음 1) 문제는 빈이 두 번 생성된다는 것입니다.
내가 그걸 제거 만한다면 :
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
그러나
[특별한]
전체 Web.xml은 다음과 같습니다.
<web-app 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>
<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>
<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>/api/secure/*</url-pattern>
</filter-mapping>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/mvc-dispatcher-servlet.xml
</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
여기에 내 mvc-dispatcher-servlet.xml이 있습니다.
<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:tx="http://www.springframework.org/schema/tx"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.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.1.xsd">
<mvc:annotation-driven/>
<context:annotation-config/>
<context:component-scan base-package="com.ge.wtracker"/>
<context:property-placeholder location="classpath*:META-INF/spring/*.properties"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
<!--Java Persistence API config-->
<jpa:repositories base-package="com.ge.wtracker.repository"/>
<!--JPA and Database Config-->
<tx:annotation-driven transaction-manager="transactionManager"/>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="defaultPersistenceUnit"/>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>
<bean class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" id="dataSource">
<property name="driverClassName" value="${database.driverClassName}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
<property name="testOnBorrow" value="true"/>
<property name="testOnReturn" value="true"/>
<property name="testWhileIdle" value="true"/>
<property name="timeBetweenEvictionRunsMillis" value="1800000"/>
<property name="numTestsPerEvictionRun" value="3"/>
<property name="minEvictableIdleTimeMillis" value="1800000"/>
<property name="validationQuery" value="SELECT 1"/>
</bean>
<!--Spring Security-->
<security:http create-session="stateless" entry-point-ref="restAuthenticationEntryPoint" authentication-manager-ref="authenticationManager">
<security:intercept-url pattern="/api/secure/**" access="ROLE_USER" />
<security:custom-filter ref="customRestFilter" position="BASIC_AUTH_FILTER" />
</security:http>
<!-- Configures the authentication entry point that returns HTTP status code 401 -->
<bean id="restAuthenticationEntryPoint" class="com.ge.wtracker.web.security.RestAuthenticationEntryPoint">
<property name="realmName" value="Not Authorized" />
</bean>
<security:authentication-manager alias="authenticationManager">
<security:authentication-provider ref="restAuthenticationProvider" />
</security:authentication-manager>
<!--The customRestFilter responsibles for retrieving and manipulating any request data to pass to the authentication
provider to authenticate.-->
<bean id="customRestFilter" class="com.ge.wtracker.web.security.RestSecurityFilter">
<constructor-arg name="authenticationManager" ref="authenticationManager" />
<constructor-arg name="authenticationEntryPoint" ref="restAuthenticationEntryPoint" />
</bean>
<bean id="restAuthenticationProvider" class="com.ge.wtracker.web.security.RestAuthenticationProvider" />
</beans>
해결법
-
==============================
1.서블릿 컨테이너 라이프 사이클 동안 컨테이너는 먼저 ServletContextListener를 초기화 한 다음 필터 및 서블릿 인스턴스를 초기화합니다.
서블릿 컨테이너 라이프 사이클 동안 컨테이너는 먼저 ServletContextListener를 초기화 한 다음 필터 및 서블릿 인스턴스를 초기화합니다.
Spring 웹 애플리케이션은 일반적으로 루트 컨텍스트와 디스패처 서블릿 컨텍스트의 두 컨텍스트를로드한다. ContextLoaderListener 클래스는 응용 프로그램 (또는 루트) 컨텍스트를로드하는 ServletContextListener입니다. 아래와 같이 web.xml에 주어진대로 contextConfigLocation이라는 컨텍스트 매개 변수를 통해로드 할 파일을 식별합니다
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/mvc-dispatcher-servlet.xml </param-value> </context-param>
또는 기본적으로 /WEB-INF/applicationContext.xml에서 파일을 찾는다. contextConfigLocation으로 /WEB-INF/mvc-dispatcher-servlet.xml을 지정 했으므로 해당 컨텍스트가로드됩니다.
이 작업이 완료되면 컨테이너는 DispatcherServlet을 초기화합니다. DispatcherServlet은 컨텍스트도로드합니다. 아래의 web.xml에 주어진대로 contextConfigLocation이라는 이름을 가진 init-param 요소를 통해 파일로드를 식별합니다
<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/spring/appServlet/some-random-location.xml</param-value> </init-param> </servlet>
또는 기본적으로 /WEB-INF/name-of-your-servlet-servlet.xml에서 파일을 찾는다. 즉,
요소의 값을 취하여 -servlet.xml을 추가하고 WEB-INF에서 찾습니다. contextConfigLocation이라는 이름으로 init-param을 지정하지 않았으므로 이름이 mvc-dispatcher이므로 DispatcherServlet은 /WEB-INF/mvc-dispatcher-servlet.xml에 컨텍스트 파일을로드합니다. DispatcherServlet에 의해로드 된 컨텍스트는 ContextLoaderListener에 의해로드 된 Bean에 액세스 할 수 있으므로 그 이유를 루트 컨텍스트 (및 기타 자식)라고합니다.
이 모든 것은 ContextLoaderListener와 DispatcherServlet이 /WEB-INF/mvc-dispatcher-servlet.xml의 같은 파일에서 XmlWebApplicationContext를로드 할 때마다 ApplicationContext의 복사본을 생성하고 있다고 말할 수 있습니다.
전체 응용 프로그램에서 사용할 수 있어야한다고 생각되는 bean 또는 구성을 식별하고 ContextLoaderListener가로드 할 파일에 넣으십시오. DispatcherServlet에 사용할 수 있어야한다고 생각하는 bean 또는 구성을 식별하여 해당 컨텍스트 파일에 넣으십시오.
-
==============================
2.http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch16s02.html
http://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch16s02.html
따라서 컨텍스트 매개 변수를 제거 할 수 있습니다.
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/mvc-dispatcher-servlet.xml </param-value> </context-param>
-
==============================
3.그런 다음 Spring MVC는 새로운 any-name.xml을 만들고 context specific beans를 배치한다. Spring-security.xml 및 보안 Bean로드.
그런 다음 Spring MVC는 새로운 any-name.xml을 만들고 context specific beans를 배치한다. Spring-security.xml 및 보안 Bean로드.
새 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:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd 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/task http://www.springframework.org/schema/task/spring-task-3.1.xsd"> <mvc:annotation-driven/> <context:component-scan base-package="com"/> <task:annotation-driven/> <bean id="propertyConfigurer" class="org.springframework.beans.factory. config.PropertyPlaceholderConfigurer"> <property name="location" value=""/> <property name="locations"> <list> <value>/WEB-INF/jdbc.properties</value> </list> </property> </bean> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.databaseurl}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> </beans>
이제 이것을 web.xml에 포함하십시오.
<context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/login-security.xml, /WEB-INF/application-context.xml </param-value> </context-param>
이것이 당신을 도울 수 있기를 바랍니다.
from https://stackoverflow.com/questions/19826228/spring-web-security-web-xml-mvc-dispatcher-bean-is-created-twice by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring MVC : 맞춤 404 오류 페이지를 반환하는 방법? (0) | 2018.12.15 |
---|---|
[SPRING] 스프링 부트의 핫 스와핑 (0) | 2018.12.15 |
[SPRING] OAuth2 인증 서버 / 사용자 엔드 포인트에서 맞춤 사용자 정보를 얻는 방법 (0) | 2018.12.14 |
[SPRING] 요소 'beans'의 선언을 찾을 수 없습니다. (0) | 2018.12.14 |
[SPRING] spring-context.xml의 위치 (0) | 2018.12.14 |