Spring

Spring/이론

[AOP] @Aspect 프록시, 포인트컷, 어드바이스

스프링 어플리케이션에 프록시를 적용하려면 어드바이저를 스프링 빈으로 등록하면 된다. 이 전 글들에서 계속 언급돼 왔다시피 어드바이저 = 포인트컷 + 어드바이스 이다. 포인트컷: 적용 조건 어드바이스: 추가할 부가 기능 이 어드바이저를 등록하려면 긴 코드를 작성해줘야 했다. 하지만 우리의 스프링 부트는 이런 길고 반복되는 코드를 그냥 보고있지 않는다. @Aspect 어노테이션은 이 반복되는 코드(어드바이저 등록)를 자동화해준다. 1. @Aspect 사용법 사용 방법은 너무나도 간단하다. @Slf4j @Aspect public class LogTraceAspect { private final LogTrace logTrace; public LogTraceAspect(LogTrace logTrace) { thi..

Spring/이론

[스프링 고급] 빈 후처리기

빈 후처리기는 스프링 컨테이너에 빈이 등록되기 전 로직을 처리할 수 있게 해주는 기능이다. 빈을 직접 등록해서 하면 되는데 왜 굳이 또 중간에 뭘 넣는가 의문이 들 수 있다. 그냥 Configuration 파일 만들어서 직접 주입하면 되는거 아닌가 생각이 들었다. 하지만 코드를 작성할 때 빈 객체를 등록할 때 보통은 @Bean 보다는 @Component를 더 선호할 것이다. 빈 후처리기는 @Component로 바로 빈으로 등록되기 전 가로채서 로직을 처리할 수 있게 마지막 기회를 준다. 간편하게 @Component로 빈이 자동 등록되는데 굳이 가로채야 하는 이유에는 어떤 것이 있을까? 지금까지 공부한 프록시가 되겠다. 프록시 내에 여러 부가 기능들을 넣어두고 권한 설정도 해놨는데 (추가하고 싶은데) 냅다..

Spring/이론

[스프링 기초] Bean, 의존성 주입 DI에 대한 나만의 고찰

그동안 김영한님의 스프링 고급편까지 달려오면서 점점 기초적인 Bean에 대한 정의가 흔들리기 시작했다. 그래서 결국 Bean이란 무엇인가? 스프링을 오래 사용하면서 이 단어에 익숙해졌지만 혼자 명확히 제대로 짚어보기는 너무 미뤘던 것 같다. 이 게시글에서는 Bean에 대한 정의 및 의존성 주입에 대해 다시 한번 짚어보고자 한다. Spring이라는 프레임워크에서 빈은 스프링이 관리하는 객체라고 한다. 별로 와닿지 않는다. 코드가 객체를 어떻게 관리하지? 그럼 자바 인스턴스와 빈은 같은건가? 뭐가 다른거지? 둘은 다르지 않다. 빈은 자바 인스턴스의 종류 중에 하나일 뿐이다. 스프링 빈 등록에 대한 대략적인 그림 흐름은 이렇다. 그렇다면 그냥 객체와 인스턴스 개념 외에 빈이라는 개념이 필요한 이유는 뭘까? 이..

Spring/이론

[AOP 기반] 프록시 팩토리, 포인트컷, 어드바이스, 어드바이저란?

프록시 팩토리란 무엇일까? 자바 공부와 디자인 패턴을 공부하면서 깨달은 것이 한가지 있다. 공통적으로 사용되는 변수들은 대체적으로 단순하고 직관적이다. @@팩토리 라고 붙은 변수들은 말 그대로 @@를 공장처럼 찍어내는 역할을 한다. 그렇다면 프록시 팩토리는 무슨 역할을 하겠는가? 프록시를 만들어내는 역할을 한다. 프록시 팩토리는 클라이언트로부터 요청이 왔을 때, 인터페이스 기반인 JDK 동적 프록시를 생성할지 클래스 기반인 CGLIB를 호출할 지 선택해 반환해준다. 이 로직이 어떻게 가능한가. JDK 동적 프록시를 생성할 때와 CGLIB를 생성할 때의 이후에 동일한 로직이 호출되게 해주면 된다. 아직 이유는 정확히 모르겠지만 AOP에서는 인터페이스가 있어도 CGLIB를 주로 호출한다고 한다. 이에 대한 ..

Spring/이론

프록시 형태 별 차이 (인터페이스 VS 클래스)

인터페이스 형태가 아닌 클래스 형태에 대해서 프록시를 적용해야할 때가 있을 수 있다. 이럴 때는 어떻게 해야할까? 인터페이스를 implements 하는 것이 아닌 클래스를 extends 해주면 된다. 그 다음은 동일하게 @Override를 해줘서 내부 메소드를 구현해 덮어써주면 된다. 다만 클래스 형태에 프록시를 적용할 때는 신경써줘야 할 점이 있다. 자바 기본 문법에 의해 자식 클래스를 생성할 때는 항상 super()로 부모 클래스의 생성자를 호출해야 한다. 이 부분을 생략하면 기본 생성자가 호출되는데 부모 클래스에서 기본 생성자가 없는 경우 파라미터를 넣어서 super(파라미터) 형식으로 받아야 한다. 프록시는 부모 객체의 기능을 사용하지 않기 때문에 super(null)을 입력하면 되긴 한다. 인터..

Spring/이론

[JPA] 응답 값으로 DTO를 전달해야 하는 이유

엔티티를 직접 응답값에 리턴할 경우 엔티티에 보여주기 용 불필요한 로직이 추가된다. 프레젠테이션 계층을 위한 로직이 추가된다. 응답 스펙을 맞추기 위한 로직이 추가된다. @JsonIgnore, 별도의 뷰 로직 등 실무에서는 용도에 따라서 같은 엔티티여도 여러 API에서 이용될 수 있다. 따라서 한 엔티티에 각 API를 위한 프레젠테이션 응답 로직을 전부 담기는 어렵다. 컬렉션을 직접 반환하면 항후 API 스펙을 변경하기 어렵다. 별도로 Result용 클래스 생성으로 해결한다. 상기와 같은 이유로 API 응답 스펙에 맞추어 별도의 DTO를 정의, 반환한다. Result용 클래스 예시 // Result의 사용처 public Result Member() { List collect = memberService...

Spring/이론

[JPA] 준영속 엔티티란? 더티체킹이란?

준영속 엔티티란? 영속성 컨텍스트가 더는 관리하지 않는 엔티티를 말한다. 영속 상태로 DB에 저장된 적이 있는, 식별자가 기존재하는 엔티티이다. Book book = new Book(); book.setId(param.getId()); 여기서 book은 새로운 객체이다. 하지만 기존의 식별자를 가지고 있다. 이러한 경우에는 준영속 엔티티로 볼 수 있다. 준영속 엔티티는 JPA가 관리를 하지않아 객체 내의 값을 수정해도 DB에 업데이트가 일어나지 않는다. 준영속 엔티티를 수정하는 방법 그러면 이미 영속성이 끊어진 준영속 엔티티로 어떻게 DB에 업데이트를 일으킬 수 있을까? 변경 감지 기능 (Dirty Checking) 사용 병합 (merge) 사용 변경 감지 기능 사용 @Transactional void ..

Spring/이론

동적 쿼리 VS 정적 쿼리 차이, 예시

정적 쿼리: 항상 동일한 쿼리 동적 쿼리: 조건에 따라 달라지는 쿼리 정적 쿼리 예시: (쿼리가 일정하다) SELECT * FROM MEMBER WHERE ID = 1016 동적 쿼리 예시: (조건에 따라 쿼리가 바뀐다) SELECT * FROM MEMBER WHERE IF (ID = 1016) THEN ID = 1016 ELSE ID = 0224 END IF; 이 경우를 보면 (문법은 살짝쿵 무시해주자) ID가 1016일 경우의 쿼리는 SELECT * FROM MEMBER WHERE ID = 1016 ID가 1016이 아닐 경우의 쿼리는 SELECT * FROM MEMBER WHERE ID = 0224 이렇게 된다. 조건에 따라 동적으로 쿼리가 변하는 것이다.

레이튼
'Spring' 카테고리의 글 목록