[SPRING] 범위 '세션'이 현재 스레드에 대해 활성화되어 있지 않습니다. IllegalStateException : 스레드 바인딩 된 요청이 없습니다.
SPRING범위 '세션'이 현재 스레드에 대해 활성화되어 있지 않습니다. IllegalStateException : 스레드 바인딩 된 요청이 없습니다.
컨트롤러마다 고유 한 세션을 만들고 싶습니다. 스프링 문서에 따르면 구현에 대한 두 가지 세부 사항이 있습니다.
1. 초기 웹 구성
문서에 표시된대로 web.xml에 다음을 추가했습니다.
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
2. 범위가 지정된 bean을 종속 항목으로 사용
나는 아래와 같이 proxyMode를 제공하는 @Scope를 사용하여 빈에 주석을 붙였다.
@Controller
@Scope(value="session", proxyMode=ScopedProxyMode.TARGET_CLASS)
public class ReportBuilder implements Serializable {
...
...
}
문제
위의 구성에도 불구하고 다음 예외가 발생합니다.
업데이트 1
아래는 내 구성 요소 검사입니다. 나는 web.xml에서 다음을 가지고있다.
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.example.AppConfig</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
AppConfig.java에서는 다음과 같은 작업을 수행합니다.
@Configuration
@EnableAsync
@EnableCaching
@ComponentScan("org.example")
@ImportResource("classpath:applicationContext.xml")
public class AppConfig implements AsyncConfigurer {
...
...
}
업데이트 2
재현 가능한 테스트 케이스를 만들었습니다. 이것은 훨씬 더 작은 프로젝트이므로 차이점이 있지만 같은 오류가 발생합니다. 꽤 많은 파일이 있으므로 tar.gz를 megafileupload에 업로드했습니다.
해결법
-
==============================
1.문제는 Spring 주석이 아니라 디자인 패턴입니다. 서로 다른 범위와 스레드를 혼합합니다.
문제는 Spring 주석이 아니라 디자인 패턴입니다. 서로 다른 범위와 스레드를 혼합합니다.
싱글 톤은 어디에서나 사용할 수 있습니다. 그러나 요청에 연결된 스레드 외부에서는 세션 / 요청 범위를 사용할 수 없습니다.
비동기 작업은 요청 또는 세션이 더 이상 존재하지 않기 때문에 실행될 수 있으므로 요청 / 세션 종속 bean을 사용할 수 없습니다. 또한 별도의 스레드에서 작업을 실행하는 경우 알 수있는 방법이 없습니다. 스레드는 작성자 요청입니다 (이 경우 aop : proxy는 도움이되지 않습니다).
나는 당신의 코드가 ReportController, ReportBuilder, UselessTask, ReportPage 사이의 계약을 만들고 싶어한다고 생각한다. 간단한 클래스 (POJO)를 사용하여 UselessTask의 데이터를 저장하고 ReportController 또는 ReportPage에서 읽고 더 이상 ReportBuilder를 사용하지 않는 방법이 있습니까?
-
==============================
2.다른 사람이 같은 지점에 머물러 있다면 내 문제가 해결되었습니다.
다른 사람이 같은 지점에 머물러 있다면 내 문제가 해결되었습니다.
In web.xml
<listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener>
세션 구성 요소
@Component @Scope(value = "session", proxyMode = ScopedProxyMode.TARGET_CLASS)
pom.xml에서
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.1</version> </dependency>
-
==============================
3.원인과 가능한 해결책에 대한 더 나은 개요를 제공하므로 내 자신의 질문에 대답하고 있습니다. 나는 Martin이 원인을 지적했기 때문에 @Martin에 보너스를 줬다.
원인과 가능한 해결책에 대한 더 나은 개요를 제공하므로 내 자신의 질문에 대답하고 있습니다. 나는 Martin이 원인을 지적했기 때문에 @Martin에 보너스를 줬다.
원인
@Martin이 제안한 것처럼 다중 스레드를 사용하게됩니다. 요청 개체는 Spring 가이드에서 언급 한 것처럼이 스레드에서 사용할 수 없습니다.
해결책 1
요청 개체를 다른 스레드에서 사용할 수있게 만들 수는 있지만 시스템에 몇 가지 제한 사항이 있습니다. 이는 모든 프로젝트에서 작동하지 않을 수 있습니다. 이 솔루션은 다중 스레드 웹 응용 프로그램의 요청 범위 콩에 액세스 할 수 없습니다.
해결책 2
유일한 다른 옵션은 요청 스레드 내에서 세션 범위 Bean을 사용하는 것입니다. 내 경우에는 다음과 같은 이유로 불가능했습니다.
-
==============================
4.문서 별 :
문서 별 :
Spring MVC (DispatcherServlet에 의해 처리되지 않음) 외부에서 실행중인 경우, ContextLoaderListener뿐만 아니라 RequestContextListener를 사용해야한다.
web.xml에 다음을 추가하십시오.
<listener> <listener-class> org.springframework.web.context.request.RequestContextListener </listener-class> </listener>
그 범위에서 빈을 유지하기 위해 Spring에 세션을 제공 할 것입니다.
업데이트 : 다른 답변에 따르면, @Controller는 Spring MVC 컨텍스트에서 작업 할 때만 의미가 있으므로 @Controller가 코드에서 실제 용도로 사용되지 않습니다. 세션 범위 / 요청 범위 (특정 범위에서 bean을 주입하기 위해 Spring MVC / Controller가 필요 없음)를 사용하여 어디에서나 빈을 삽입 할 수 있습니다.
업데이트 : RequestContextListener는 요청을 현재 스레드에만 공개합니다. 두 곳에서 ReportBuilder를 자동 실행했습니다. 1. ReportPage - Spring이 동일한 웹 스레드에 있기 때문에 Spring이 보고서 작성기를 제대로 주입 한 것을 볼 수 있습니다. ReportBuilder가 ReportPage에 삽입되었는지 확인하기 위해 코드의 순서를 변경했습니다.
log.info("ReportBuilder name: {}", reportBuilder.getName()); reportController.getReportData();
나는 로그가 당신의 논리에 따라 뒤따라야한다는 것을 알았다. 단지 디버깅 목적을 위해서였다.
2. UselessTasklet - Request가 SpringControllerListener에 의해 노출되지 않는 Spring Batch에 의해 생성 된 다른 스레드이기 때문에 예외가 발생했습니다.
ReportBuilder 인스턴스를 생성하고 Spring Batch에 삽입하는 다른 로직이 있어야합니다 (Spring Batch 매개 변수 및 향후 참조를 위해 반환 할 수있는 Future
-
==============================
5.https://stackoverflow.com/a/30640097/2569475
https://stackoverflow.com/a/30640097/2569475
이번 호의 경우 위 URL에서 내 대답을 확인하십시오.
실제 웹 요청 이외의 요청 범위 Bean 사용
-
==============================
6.내 답변은 OP가 묘사하는 일반적인 문제의 특수한 경우를 말하지만, 누군가를 돕기 위해 추가 할 것입니다.
내 답변은 OP가 묘사하는 일반적인 문제의 특수한 경우를 말하지만, 누군가를 돕기 위해 추가 할 것입니다.
@ EnableOAuth2Sso를 사용할 때 Spring은 OAuth2RestTemplate을 응용 프로그램 컨텍스트에두고이 구성 요소는 스레드 바인딩 된 서블릿 관련 내용을 가정합니다.
내 코드에는 autowired RestTemplate을 사용하는 예약 된 비동기 메소드가 있습니다. 이것은 DispatcherServlet 내에서 실행되지 않지만 Spring은 OP가 설명하는 오류를 생성 한 OAuth2RestTemplate을 주입하고있었습니다.
해결책은 이름 기반 주입을 수행하는 것이 었습니다. 자바 설정에서 :
@Bean public RestTemplate pingRestTemplate() { return new RestTemplate(); }
그리고 그것을 사용하는 클래스에서 :
@Autowired @Qualifier("pingRestTemplate") private RestTemplate restTemplate;
이제 Spring은 서블릿이 필요없는 RestTemplate을 주입합니다.
-
==============================
7.프로토 타입을 제외한 기본 싱글 톤 범위와는 다른 범위가 필요한 bean에서 정의 할 필요가 있습니다. 예 :
프로토 타입을 제외한 기본 싱글 톤 범위와는 다른 범위가 필요한 bean에서 정의 할 필요가 있습니다. 예 :
<bean id="shoppingCart" class="com.xxxxx.xxxx.ShoppingCartBean" scope="session"> <aop:scoped-proxy/> </bean>
from https://stackoverflow.com/questions/21286675/scope-session-is-not-active-for-the-current-thread-illegalstateexception-no by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring - POST 후에 리디렉션 (유효성 검사 오류가있는 경우에도) (0) | 2018.12.05 |
---|---|
[SPRING] 왜 우리는 봄에 정적 필드를 autowire 수없는거야? (0) | 2018.12.05 |
[SPRING] 어쨌든 생성자 인수가 필요한 빈을 @Autowire로 보내려면? (0) | 2018.12.05 |
[SPRING] 스프링 부트, 스프링 데이터 JPA 여러 데이터 소스 포함 (0) | 2018.12.05 |
[SPRING] application.properties 파일의 Spring Boot app에 HikariCP를 어떻게 구성합니까? (0) | 2018.12.05 |