스프링(33)
-
WebSocket & STOMP 그룹 채팅방 구현하기
프로젝트에서 WebSocket과 STOMP 프로토콜을 이용해 그룹채팅방 기능을 구현했습니다. 스프린트 초반에는 댓글과 Polling 기법을 이용해 유저 간 소통하도록 하였습니다. 하지만 Polling 기법의 단점과 애플리케이션 특성을 고려하였을 때 실시간 채팅이 필요하다고 생각되어 고도화를 진행했습니다. Polling 클라이언트가 일정한 주기마다 서버로 요청을 보내는 방식입니다. 서버 데이터의 변경 여부와 상관없이 주기적으로 요청을 보내므로, 불필요한 요청에 따른 네트워크 부하가 늘어납니다. 또한 요청 인터벌을 너무 길게 잡을 경우 실시간성이 떨어지며, 짧게 잡을 경우 서버에 부하가 올라가는 trade off가 존재합니다. 실시간성이 중요하지 않거나 일정한 주기로 갱신되는 데이터를 조회할 때는 사용할 수..
2023.05.16 -
순환 참조 문제(Setter 주입 vs 생성자 주입)
순환참조란 A 클래스가 B 클래스의 Bean을 주입받고, B클래스가 A 클래스의 Bean을 주입받는 상황처럼 서로 순환되어 참조되는 경우를 말한다. 특정 클래스에서 DI를 받을 수 있는 방법은 필드 주입, Setter 주입, 생성자 주입이 대표적으로 가능하다. 이번에는 지난번 Setter 주입과 생성자 주입에서 각각 순환참조 문제가 다르게 나타나는 것을 살펴본다. 준비한 예제에서는 DependencyA와 DependencyB가 서로 순환 참조를 하고 있는 상황이다. Setter 주입의 경우 class DependencyA { private DependencyB dependencyB; @Autowired void setDependencyA(DependencyB dependencyB) { this.depen..
2022.11.02 -
ThreadLocal - 예제로 알아보는 쓰레드 로컬 (1)
쓰레드 로컬을 학습하기 위해 우선 간단한 예제 프로젝트를 만들어보자. 이번 포스팅은 예제 프로젝트를 작성하며 발생하는 문제점을 알아본다. 다음 포스팅에서 쓰레드 로컬로 해결하는 방법을 소개한다. 상품을 주문하는 프로세스로 가정하고, 일반적인 웹 애플리케이션에서 Controller --> Service --> Repository로 이어지는 흐름을 단순하게 작성한다. @Repository @RequiredArgsConstructor public class OrderRepositoryV0 { public void save(String itemId) { //저장 로직 if (itemId.equals("ex")) { throw new IllegalStateException("예외 발생!"); } sleep(100..
2022.07.07 -
[토비의 스프링 3.1] 3.3 JDBC 전략 패턴의 최적화
이전 장(3.2)에서는 전략 패턴을 사용해서 변하는 부분과 그렇지 않은 부분을 깔끔하게 분리했다. public void deleteAll() throws SQLException { StatementStrategy strategy = new DeleteAllStatement(); // 선정한 전략 클래스의 오브젝트 생성 jdbcContextWithStatementStrategy(strategy); // 컨텍스트 호출, 전략 오브젝트 전달 } 클라이언트 코드에서 구체적인 전략을 정하고, 컨텍스트에 그 전략을 파라미터로 전달해주었다. 컨텍스트도 jdbcContextWithStatementStrategy라는 메소드로 분리하였더니 다른 DAO에서도 PreparedStatement를 실행하는 JDBC의 공통 작업 ..
2022.07.07 -
@Profile 어노테이션
1) 로컬에서 애플리케이션을 실행할 때 2) 테스트를 실행할 때 3) 실제 운영을 위해 배포할 때 위의 세가지 경우에서 각각 다른 설정을 사용하고 싶고, 해당 설정에 맞는 Bean을 사용하고 싶은 경우 @Profile 어노테이션을 사용하면 좋다. 스프링은 프로필(@Profile)을 통해 런타임 환경을 설정할 수 있는 기능을 제공한다. 파일을 여러 개로 분리하는 대신에 빈 구성이 달라지는 내용을 프로필로 정의해서 만들어두고, 실행 시점(런타임)에 어떤 프로필의 빈 설정을 사용할 지 지정할 수 있는 것이다. 먼저, application.properties 설정파일을 한번 살펴보자. 하나는 java 패키지의 설정파일로, 1번 경우에 해당한다. 아래는 test 패키지 하위에 있는 application.prope..
2022.07.06 -
[토비의 스프링 3.1] 3.2 변하는 것과 변하지 않는 것
3.2.1 JDBC try/catch/finally 코드의 문제점 바로 이전 장에서는 try/catch/finally 블록을 적용해서 완성도 높은 UserDao를 작성했지만, 여전히 복잡한 것은 사실이다. try/catch/finally 블록이 2중으로 중첩되어 나오며(finally 블록에서 리소스 반환할 때에도 try/catch/finally가 한번 더 사용된다), 모든 메소드에서 try/catch/finally 블록이 반복된다. 만약 finally 블록에서 커넥션을 닫아주는 메소드를 생략한 경우에는, 테스트에 별 문제 없어보여도 애플리케이션을 운영하던 중에 서버에서 리소스가 꽉 찼다는 에러가 발생하며 서비스가 중단될 것이다. 이런 DAO는 폭탄이 될 가능성을 지니고 있다. 이 경우에는 변하지 않는, ..
2022.07.06