JAVA 104

[Netty] Netty 개요 및 간단한 예제

Netty비동기 이벤트 기반의 네트워크 애플리케이션 프레임워크HTTP뿐만 아니라 FTP, SMTP, Telnet 등 다양한 네트워크 프로토콜을 지원Java IO, NIO, Selector 기반으로 적은 리소스로 높은 성능 보장NIO는 비동기 I/O를 지원하여, 블로킹 방식의 IO에 비해 더 나은 성능을 제공NIO의 Selector는 여러 채널에서 발생하는 I/O 이벤트를 감지하고 처리불필요한 메모리 복사를 최소화하여 메모리 사용을 최적화 이벤트 모델은 매우 유연하고 확장 가능하며 필요에 따라 커스텀 이벤트 핸들러를 추가하거나 제거할 수 있음서버와 클라이언트 모두 지원하며 이를 통해 양방향 통신이 필요한 애플리케이션을 쉽게 개발할 수 있음  NIOEventLoopNetty 프레임워크에서 비동기 I/O 작업..

[Java] 자바 IO, NIO, AIO

자바 IO자바 1 버전에 최초 도입파일과 네트워크에 데이터를 읽고 쓸 수 있는 API 제공InputStream, OutputStream과 같이 byte 단위로 읽고 쓸 수 있는 streamblocking 방식으로 동작 1. InputStream바이트 스트림을 통해 데이터를 읽는 데 사용되는 추상 클래스Closable 구현체이기 때문에 명시적으로 스트림을 닫거나 try-with-resources 사용 가능파일, 네트워크 연결, 메모리 버퍼 등 다양한 소스로부터 데이터를 읽을 수 있는 표준화된 방법을 제공어떤 source로부터 데이터를 읽을지에 따라 다양한 구현체 존재FileInputStreamByteArrayInputStreamBufferedInputStreamSocketInputStream 1.1 주요 ..

[아이템 90] 직렬화된 인스턴스 대신 직렬화 프록시 사용을 검토하라

앞서 아이템 87, 아이템 88, 그리고 아이템 89에서 언급했던 것처럼 Serializable을 구현하기로 결정한 순간 언어의 생성자 이외의 방법으로도 인스턴스를 생성할 수 있게 됨에 따라 버그 및 보안 문제가 발생할 가능성이 커집니다.위 문제를 해결하기 위해 커스텀 직렬화, readObject() 또는 readResolve()를 직접 구현하여 위험성을 낮출 수 있지만, 직렬화 프록시 패턴(Serialization Proxy Pattern)을 사용하여 위험을 낮출 수도 있습니다.직렬화 프록시 패턴은 일반적으로 아이템 88에서 다룬 readObject()의 방어적 복사보다 강력함 직렬화 프록시 패턴바깥 클래스의 논리적 상태를 정밀하게 표현하는 중첩 클래스를 설계해 private static으로 선언해당 ..

JAVA/Effective Java 2024.05.19

[아이템 89] 인스턴스 수를 통제해야 한다면 readResolve보다는 열거 타입을 사용하라

싱글턴이란?클래스의 인스턴스가 오직 1개만 생성되는 것을 보장하는 디자인 패턴 싱글턴 객체를 직렬화할 때 발생하는 문제점클래스에 마커 인터페이스인 Serializable을 구현하는 순간 더 이상 싱글턴 객체가 아님아이템 87에서 언급한 커스텀 직렬화를 사용하더라도, 아이템 88에서 언급한 커스텀 readObject() 메서드를 사용하더라도 소용없음어떤 readObject() 메서드를 선언하든 해당 클래스가 초기화될 때 만들어진 인스턴스와는 별개인 인스턴스를 반환 readResolve() 기능을 이용할 때readObject()가 생성한 인스턴스를 다른 것으로 대체 가능역직렬화한 객체의 클래스가 readResolve() 메서드를 적절히 구현했다면 역직렬화 후 새로 생성된 객체를 인수로 해당 메서드가 호출되고..

JAVA/Effective Java 2024.05.18

[아이템 88] readObject 메서드는 방어적으로 작성하라

아이템 50에서 불변인 날짜 범위 클래스를 생성할 때 가변 객체인 Date 필드를 이용했습니다.이 때문에 불변식을 지키고 유지하기 위해 모든 생성자와 접근자에 Date 객체를 방어적으로 복사하느라 코드가 상당히 길어졌던 것을 기억할 것입니다.   아이템 87에서 언급했다시피 객체의 물리적 표현과 논리적 표현이 동일할 경우 기본 직렬화를 사용해도 됩니다.따라서 위 Period 클래스가 단순히 마커 인터페이스인 Serializable를 구현하도록 수정하면 완벽한 직렬화 적용이 완료되었을 것이라고 생각이 들 것입니다.하지만 위와 같이 적용해서는 주요한 Date 객체의 불변식을 보장하지 못합니다. Period 객체가 단순히 Serializable을 구현했을 때 발생하는 문제점readObject() 메서드가 실질..

JAVA/Effective Java 2024.05.18

[아이템 87] 커스텀 직렬화 형태를 고려해보라

개발 일정에 쫓기는 상황이라면 세부적인 구현에 집중하기보다는 이번 릴리즈에 대충 동작은 하도록 API 설계에 노력을 집중하는 편이 낫습니다.하지만 클래스가 Serializable 구현체이고 기본 직렬화 형태를 사용한다면 기본 직렬화 형태를 버릴 수 없게 되기 때문에 다음 릴리즈 때 버리려 한 대충 동작하는 현재의 구현에 영원히 발이 묶이게 됩니다. 먼저 고민해보고 괜찮다고 판단될 경우에만 기본 직렬화 형태를 사용하자기본 직렬화 형태는 유연성, 성능, 정확성 측면에서 신중히 고민한 후 합당할 때만 사용하는 것을 권장직접 설계하더라도 기본 직렬화 형태와 거의 같은 결과가 나올 경우에만 기본 형태를 사용기본 직렬화 형태는 해당 객체를 루트로 하는 객체 그래프의 물리적 모습을 나름 효율적으로 인코딩한 형태객체가..

JAVA/Effective Java 2024.05.14

[아이템 86] Serializable을 구현할지는 신중히 결정하라

클래스 인스턴스를 직렬화하기 위해서는 단순히 마커 인터페이스인 Serializable을 구현하면 됩니다.이처럼 너무 쉽게 적용할 수 있기 때문에 프로그래머가 특별히 신경 쓸 것이 없다는 오해가 생길 수 있지만 실제로는 직렬화를 적용하는 것은 아주 값비싼 일입니다. Serializable을 구현할 경우 릴리즈한 뒤에는 수정하기 어려움클래스가 Serializable 구현체일 경우 직렬화 형태인 바이트 스트림 인코딩도 하나의 공개 API가 됨자바는 하위 호환성을 지원하는 것을 추구하기 때문에 직렬화된 클래스가 널리 쓰이는 라이브러리에 포함될 경우 릴리즈 이후에는 직렬화 형태도 영원히 지원해야 함클래스의 private과 package-private 인스턴스 필드마저 API로 공개하는 꼴이 되어 객체지향의 핵심인..

JAVA/Effective Java 2024.05.12

[아이템 85] 자바 직렬화의 대안을 찾으라

자바 직렬화란?자바 객체를 바이트 스트림으로 변환하는 메커니즘객체를 파일에 저장하거나 네트워크를 통해 DB 혹은 메모리로 전송할 때 유용직렬화된 객체는 나중에 다시 역직렬화될 수 있어 객체의 상태를 보존하고 복원할 수 있음직렬화를 사용하기 위해서는 클래스가 Serializable 인터페이스 구현체여야 함직렬화된 객체는 ObjectOutputStream을 사용하여 생성된 출력 스트림으로 쓰이며 이를 통해 객체를 스트림에 쓰면 자동으로 필드 값들이 바이트로 변환되어 출력역직렬화는 직렬화된 객체를 읽어와서 자바 객체로 변환하는 것이며 이를 위해 ObjectInputStream을 사용직렬화를 통해 생성된 바이트 스트림은 플랫폼에 독립적이기 때문에 타 플랫폼에서도 역직렬화가 가능 자바 직렬화의 취약점앞선 설명만 ..

JAVA/Effective Java 2024.05.12

[Java] CompletableFuture

동시성 프레임워크 정리 글에서 언급했다시피 Future는 작업의 결과를 가져올 때까지 blocking 되고, 작업을 조합하거나 예외 처리하는 것이 어려웠습니다.이 문제를 해결하기 위해 자바 8에서 CompletableFuture가 등장했고 이번 게시글에서는 다음 내용을 간단히 정리해 보겠습니다.동기 vs 비동기CompletableFuture 개요CompletableFuture APIForkJoinPool 1. 동기 vs 비동기 1.1 동기(Synchronous)작업이 순차적으로 실행되며 한 작업의 시작과 완료가 다른 작업의 시작과 완료와 밀접하게 연결된 방식하나의 작업이 실행 중인 동안 다른 작업은 대기해야 함작업의 결과를 기다린 후 다음 작업이 진행작업은 한 번에 하나씩 진행하며 작업을 건너뛰거나 빠뜨..

[Java] ThreadPoolExecutor

ThreadPoolExecutor는 ExecutorService를 구현한 클래스로서 매개변수를 통해 다양한 설정과 조정이 가능하며 사용자가 직접 컨트롤할 수 있는 쓰레드 풀입니다.기존의 Executors가 생성하는 ThreadPool은 옵션 세부 튜닝이 어려웠던 반면 ThreadPoolExecutor는 이를 보완함 ThreadPoolExecutor는 다양한 구성 옵션을 통해 동작을 조정할 수 있으며 주요 구성 요소는 다음과 같습니다.corePoolSizemaximumPoolSizekeepAliveTimeBlockingQueueRejectedExecutionHandlerThreadPoolExecutor Hook 1. corePoolSize & maximumPoolSizeThreadPoolExecutor는 ..