[SPRING] 스프링 루트 애플리케이션 컨텍스트와 서블릿 컨텍스트 혼동
SPRING스프링 루트 애플리케이션 컨텍스트와 서블릿 컨텍스트 혼동
내 webapp을 액세스 가능하게 만들기 위해 서블릿 컨텍스트에 @Controller라는 주석이 달린 클래스를 등록해야한다는 것을 알고있다. 일반적으로, 나는 다음과 같은 방법으로 그것을한다 :
@Configuration
@EnableWebMvc
@ComponentScan({"foo.bar.controller"})
public class WebConfig extends WebMvcConfigurerAdapter {
//other stuff like ViewResolvers, MessageResolvers, MessageConverters, etc.
}
다른 모든 구성 클래스를 루트 응용 프로그램 컨텍스트에 추가했습니다. 다음은 디스패처 초기화 프로그램의 일반적인 모습입니다.
public class DispatcherServletInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class, ServiceConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
하지만 웹 소켓을 사용하기 시작하면 점점 더 흥미로워지고 있습니다. 웹 소켓을 작동 시키려면 WebSocket Config.class를 서블릿 컨텍스트에 넣어야합니다. WebSocketConfig의 예가 아래와 같습니다.
@Configuration
@EnableScheduling
@EnableWebSocketMessageBroker
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer {
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/chat").withSockJS();
}
@Override
public void configureClientInboundChannel(ChannelRegistration channelRegistration) {
channelRegistration.taskExecutor().corePoolSize(4).maxPoolSize(8);
}
@Override
public void configureClientOutboundChannel(ChannelRegistration channelRegistration) {
channelRegistration.taskExecutor().corePoolSize(4).maxPoolSize(8);
}
@Override
public void configureMessageBroker(MessageBrokerRegistry registry) {
registry.enableSimpleBroker("/queue", "/topic");
registry.setApplicationDestinationPrefixes("/app");
}
}
또한 주제에 대한 메시지를 보낼 서비스를 만들었습니다.
@Service
public class TimeServiceWsImpl implements TimeServiceWs {
@Autowired
private SimpMessagingTemplate messagingTemplate;
@Override
public void sentCurrentTime() {
long currentTime = System.currentTimeMillis();
String destination = "/topic/chatty";
logger.info("sending current time to websocket /topic/time : " + currentTime);
this.messagingTemplate.convertAndSend(destination, currentTime);
}
}
다른 서비스 (autowire)에서이 서비스를 사용해야합니다. 이제 교착 상태에 빠졌습니다.
내가 뭘해야되는거야? 루트 컨텍스트 내부에 있어야하는 것은 무엇입니까? 서블릿 컨텍스트 내부에 있어야하는 것은 무엇입니까? 그리고이 문맥의 차이점을 다시 한번 분명히 해 주시겠습니까?
추가 정보가 필요하면 알려주십시오.
해결법
-
==============================
1.대부분의 Spring MVC 애플리케이션은 모든 서비스 계층 / DAO 계층 Bean을 포함하는 하나의 루트 컨텍스트와 각 서블릿의 컨트롤러를 포함하는 애플리케이션의 스프링 디스패처 서블릿 당 하나의 서블릿 컨텍스트를 포함합니다.
대부분의 Spring MVC 애플리케이션은 모든 서비스 계층 / DAO 계층 Bean을 포함하는 하나의 루트 컨텍스트와 각 서블릿의 컨트롤러를 포함하는 애플리케이션의 스프링 디스패처 서블릿 당 하나의 서블릿 컨텍스트를 포함합니다.
하나의 애플리케이션에 URL / 쇼핑 / * 및 URL / reporting / *에 대한 하나의 서블릿 디스패처가있을 수 있다는 아이디어가 있습니다. 각 서블릿 디스패처는 각각 컨트롤러 세트를 가지고 있습니다.
하나의 서블릿 디스패처의 컨트롤러는 서로 격리되어 있습니다. 즉, 스프링 콩이기는하지만 서로 주입 할 수 없습니다.
루트 컨텍스트의 서비스 레이어와 DAO 빈은 모든 서블릿 컨텍스트에서 볼 수 있으므로 서비스 레이어 빈은 모든 컨트롤러에 삽입 될 수 있지만 다른 방법으로는 삽입 될 수 없습니다.
루트 컨텍스트는 컨트롤러 서블릿 컨텍스트 / 컨텍스트의 부모라고합니다.
그것은 모두 서로에게서 콩 그룹을 분리하여 아무런 관련없는 의존성이 없도록 보장하는 메커니즘을 의미합니다.
이것을 감안할 때 질문을 통해 :
-
==============================
2.WebSocket 관련 설정은 DispatcherServlet 설정에 속합니다. 모든 HTTP 핸드 셰이크가 처리기 매핑을 통해 DispatcherServlet에 의해 처리 된 후.
WebSocket 관련 설정은 DispatcherServlet 설정에 속합니다. 모든 HTTP 핸드 셰이크가 처리기 매핑을 통해 DispatcherServlet에 의해 처리 된 후.
웹 애플리케이션에 단 하나의 DispatcherServlet 만있는 배치 시나리오에서 단일 Spring 컨텍스트를 사용할 수 있어야한다. AbstractAnnotationConfigDispatcherServletInitializer (SPR-11357 참고)에 버그가 있었지만 예를 들어 Spring Security를 사용하면 설정을 루트 컨텍스트로 통합하는 것이 더 효과적입니다. DispatcherServlet 컨텍스트로 통합하는 것도 가능해야하지만 예외가 있다고 썼다. 예외 세부 사항을 제공 할 수 있습니까?
또한 root 및 DispatcherServlet 컨텍스트를 모두 가질 수있는 옵션입니다. 이 경우 WebSocket 구성은 DispatcherServlet 컨텍스트에 있고 SimpMessagingTemplate을 루트 컨텍스트의 Bean에 삽입 할 수 없습니다. 각각의 DispatcherServlet (또는 다른 서블릿)과 함께 갈 하나의 SimpMessagingTemplate이 있기 때문에 실제로 의미가 있습니다. 필요한 것은 웹 레이어 구성 요소이며, SimpMessagingTemplate과 함께 주입 될 수있는 Service Layer Bean (예 : TimeServiceWs 위의 예제)을 감싸는 얇은 래퍼 일 수 있습니다. 이 웹 레이어 구성 요소는 본질적으로 브리지 역할을합니다.
from https://stackoverflow.com/questions/21319450/spring-root-application-context-and-servlet-context-confusion by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring ThreadPoolTaskExecutor는 하나의 쓰레드만을 실행합니다. (0) | 2019.03.04 |
---|---|
[SPRING] Spring 3 MVC : 사용자 정의 유효성 검사기로 유효성 검사 메시지 표시 (0) | 2019.03.03 |
[SPRING] wsdl을 사용하여 SPRING-WS에서 웹 서비스 서비스 사용 (0) | 2019.03.03 |
[SPRING] 단순히 pom.xml에 slf4j를 추가하면 log4j가 어떻게 래핑됩니까? (0) | 2019.03.03 |
[SPRING] Spring + Springfox + 헤더 매개 변수 (0) | 2019.03.03 |