본문 바로가기
Projects/SNS프로젝트

[채팅] @ServerEndpoint 사용 시 DI가 안되는 문제

by 젊은오리 2022. 12. 12.
728x90

 

문제 발생

웹소켓을 이용한 채팅을 구현하는 도중 내가 정의한 @ServerEndpoint을 붙인 ChatService에서 다른 객체를 주입하지 못하는 상황이 발생했다. 즉, 아래와 같이 chatRoomService를 불러오지 못한다.

@RequiredArgsConstructor
@Service
@ServerEndpoint(value="/chatroom/{roomId}/mychat/{userId}")
public class ChatService {
   private final ChatRoomService chatRoomService;

 

 

원인 분석

@ServerEndPoint가 붙은 클래스는 웹소켓이 연결될때마다 객체가 생성되기 때문에 @Autowired가 설정된 멤버가 정상적으로 초기화되지 않는다. @Component 가 붙은 클래스들이 스프링빈에 자동으로 등록되어, 스프링에 의해서 싱글톤으로 객체들이 관리되는 모습과는 다른 모습이다.

 

 

해결

따로 Config클래스를 정의하여 ServerEndpoint의 컨텍스트에 BeanFactory 혹은 ApplicationContext를 연결해주면 된다.

package com.cos.photogramstart.config.webSocket;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ServerEndpointConfigurator extends javax.websocket.server.ServerEndpointConfig.Configurator implements ApplicationContextAware {
    private static volatile BeanFactory context;

    @Override
    public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
        return context.getBean(clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ServerEndpointConfigurator.context = applicationContext;
    }
}

 

 

@ServerEndpoint가 붙은 클래스에는 configurator를 다음과 같이 붙여준다.

@RequiredArgsConstructor
@Service
@ServerEndpoint(value="/chatroom/{roomId}/mychat/{userId}",configurator = ServerEndpointConfigurator.class)
public class ChatService {

    private final ChatRoomService chatRoomService;

 

 

 

728x90

댓글