기본 콘텐츠로 건너뛰기

라벨이 Java인 게시물 표시

동기와 비동기, 블로킹과 논블로킹을 호출 흐름으로 구분하기

동기와 비동기, 블로킹과 논블로킹을 호출 흐름으로 구분하기 빠른 답 동기와 비동기는 결과를 호출 흐름 안에서 기다릴지, 나중에 별도 흐름으로 받을지의 차이다. 블로킹과 논블로킹은 호출한 스레드가 멈춰서 기다리는지, 제어권을 돌려받아 다음 일을 할 수 있는지의 차이다. 비동기 API를 써도 결과를 바로 get() 이나 join() 으로 기다리면 다시 블로킹 구간이 생긴다. Spring @Async 는 프록시와 Executor 위에서 동작하므로 내부 호출, 예외, 트랜잭션, 스레드풀 포화 상태를 함께 봐야 한다. 목차 한눈에 비교 시간 흐름으로 이해하기 왜 헷갈릴까 동기와 블로킹이 항상 같은 말은 아니다 코드와 출력으로 보는 실행 시점 값, 상태, 오류의 의미 현재 기준 버전과 마이그레이션 포인트 Spring Async 설정과 반환 타입 내부 호출, 예외, 트랜잭션 함정 디버깅과 운영 로그 한눈에 비교 관계 기준 동기와 비동기는 호출자와 작업 결과가 같은 흐름에 묶이는지로 나뉜다. 제어권 기준 블로킹과 논블로킹은 호출 후 현재 스레드가 대기 상태에 들어가는지로 나뉜다. 값 기준 동기 호출은 대개 T 또는 예외를 돌려주고, 비동기 호출은 CompletableFuture<T> 처럼 나중의 완료 상태를 나타내는 핸들을 돌려준다. 오류 기준 동기 오류는 호출 지점의 try-catch 에서 보이고, 비동기 오류는 완료 핸들러, get() , join() 같은 관찰 지점에서 보인다. Spring 기준 @Async 는 호출자 흐름을 먼저 반환시킬 수 있지만, 작업 스레드 안에서 JDBC, 파일, 외부 API를 호출하면 그 스레드는 여전히 블로킹될 수 있다. 시간 흐름으로 이해하기 호출 시작 호출자는 작업을 요청하고 결과가 필요한지, 나중에 받아도 되는지를 정한다. → 제어권 반환 동기 호출은 보통 결과가 나올 때까지 같은 흐름에 머물고, 비동기 호출은 완료 전에도 핸들을 돌려줄 수 있다. → 대기 구간 블로킹이면 현재 스레드가 멈추고, 논블로킹이...

Spring 스테레오타입 애너테이션 차이: Component, Controller, Service, Repository를 언제 써야 할까

Spring 스테레오타입 애너테이션 차이: Component, Controller, Service, Repository를 언제 써야 할까 빠른 답 @Service , @Controller , @Repository 는 모두 @Component 기반이지만 계층 의미와 일부 런타임 동작이 다르다. Spring 6 이상, 현재 Spring Framework 7 기준에서는 @RequestMapping 만 붙은 @Component 가 MVC 핸들러로 등록되지 않는다. @Repository 는 데이터 접근 예외를 Spring의 DataAccessException 계층으로 변환하는 흐름과 연결된다. 계층별 애너테이션은 요청 처리, 트랜잭션, AOP, 테스트 범위를 읽는 기준이 된다. 목차 한눈에 비교 시간 흐름으로 이해하기 왜 모두 Bean인데 다르게 쓰는가 현재 버전 기준으로 달라진 부분 요청부터 응답까지의 코드 구조 설정과 디버깅 단서 계층별로 잘못 섞이기 쉬운 지점 공식 문서에서 확인할 지점 한눈에 비교 Bean 등록 네 애너테이션 모두 컴포넌트 스캔 대상이 될 수 있다. @Controller , @Service , @Repository 가 @Component 의 구체화된 스테레오타입이기 때문이다. 역할 표현 @Component 는 일반 Bean, @Controller 는 웹 요청 처리, @Service 는 비즈니스 흐름, @Repository 는 데이터 접근 계층을 나타낸다. 요청 매핑 현재 Spring MVC에서는 타입 레벨에 @Controller 또는 이를 포함한 @RestController 가 있어야 핸들러 후보로 인식된다. 예외 변환 @Repository 는 영속성 기술별 예외를 Spring의 데이터 접근 예외 계층으로 바꾸는 후처리와 맞물린다. 운영 단서 Actuator mappings, AOP 포인트컷, 슬라이스 테스트에서 계층별 애너테이션은 분류 기준으로 쓰인다. 네 애너테이션의 차이는 “Bean이 되느냐”만 보면 작아 보인다. 하지...

Java에서 ==와 equals는 언제 다르게 동작할까

Java에서 ==와 equals는 언제 다르게 동작할까 빠른 답 객체에서 == 는 두 변수가 같은 객체를 가리키는지 확인하는 참조 비교다. equals 는 클래스가 정한 논리적 동등성 기준을 실행하는 메서드다. 직접 만든 값 객체에서 equals 를 재정의했다면 hashCode 도 같은 기준으로 맞춰야 한다. String 과 Integer 에서 == 가 true 로 보일 때가 있지만, 캐싱과 재사용의 결과일 수 있어 값 비교 기준으로 삼기 어렵다. 목차 왜 헷갈릴까 한눈에 비교 시간 흐름으로 이해하기 직접 만든 객체의 동등성 기준 String 비교에서 결과가 갈리는 이유 Integer와 래퍼 클래스의 캐싱 hashCode를 함께 맞춰야 하는 이유 값 객체라면 record도 선택지가 된다 흔한 오해 왜 헷갈릴까 Java에서 “같다”는 말은 두 가지 질문으로 나뉜다. 하나는 “두 변수가 같은 객체를 가리키는가?”이고, 다른 하나는 “두 객체를 같은 값으로 볼 수 있는가?”이다. 예를 들어 new Apple(100) 을 두 번 호출하면 무게가 같은 사과 객체 두 개가 생긴다. 이 둘은 값 관점에서는 같다고 볼 수 있지만, 객체 자체는 서로 다르다. == 는 앞의 질문, 즉 같은 객체인지 묻는다. equals 는 뒤의 질문, 즉 클래스가 정의한 값 기준에 따라 같은지 묻는다. 이 차이는 문법 암기보다 런타임 의미에 가깝다. 변수에는 객체가 직접 들어 있는 것이 아니라 객체를 가리키는 참조가 들어 있고, equals 는 그 참조가 가리키는 객체의 메서드로 실행된다. 한눈에 비교 비교 기준 == 는 참조를 비교하고, equals 는 클래스가 정의한 동등성 기준을 비교한다. 기본 동작 Object.equals 는 기본적으로 this == obj 와 같은 참조 비교 의미를 가진다. 변경 가능성 == 의 동작은 바꿀 수 없지만, equals 는 클래스에서 재정의할 수 있다. 컬렉션 영향 HashSet , HashMap 은 hashCode 로 후보 위치를...