Skip to content

Latest commit

 

History

History
138 lines (90 loc) · 7.05 KB

README.md

File metadata and controls

138 lines (90 loc) · 7.05 KB

spring-core-advanced-study

인프런 스프링 핵심 원리 - 고급편

쓰레드 로컬 (ThreadLocal)

  • 싱글톤으로 등록된 스프링 빈의 경우 여러 스레드가 동시에 접근하는 경우 동시성 이슈 발생 > 이를 막기 위해 ThreadLocal 사용

템플릿 메서드 패턴

  • 단일 책임 원칙(SRP)으로 변경 지점을 하나로 모아서 변경에 쉽게 대처할 수 있는 구조
  • 자식 클래스는 부모 클래스의 기능 사용불가 , 부모클래스에 의존
  • 상속의 단점을 개선하는 것이 전략 패턴

전략패턴

  • 인터페이스를 사용하여 위임
  • 필드: 선 조립, 후 실행
  • 파라미터 방식: 실행 시 마다 전략을 유연하게 변경

프록시 패턴 데코레이터 패턴

  • 모양이 비슷한 두 패턴은 만든 의도에 따라 구분
  • 프록시패턴(접근제어): 다른 개체에 대한 접근을 제어하기 위한 대리자 제공
  • 데코레이터(추가책임 동적추가): 객체에 추가 책임을 동적으로 추가, 기능 확장을 유연하게 제공

인터페이스 기반 프록시 패턴

  • client > 컨트롤러proxy > 컨트롤러 > 서비스 proxy > 서비스> ...
  • 스프링 컨테이너에 프록시 객체 등록
  • 스프링 컨테이너가 실제 객체를 관리하지않음.
  • component 항상 호출

인터페이스 기반 프록시 vs 클래스 기반 프록시

  • 클래스기반 : 해당클래스, 부모 클래스 생성자 호출, final 상속 불가, 메서드 fianl 오버라이딩 불가
  • 인터페이스 기반: 인터페이스만 같으면 모든 곳 사용 가능(상속이라는 제약에서 자유로움)
    인터페이스를 나누면 구현체를 편리하게 변경 가능하지만 구현을 변경할 가능성이 없는 것은 실용적이지 않음

동적 프록시 기술

  • 리플렉션 기술: 메타정보를 동적으로 획득하고, 코드도 동적으로 호출
  • JDK 동적프록시: 인터페이스에서만 사용 가능
  • CGLIB: 구체클래스로만 동적프록시 사용, final로 선언 시 상속이나 오버라이딩 불가

프록시 팩토리

  • 서비스 추상화 덕에 CGLIB, JDK 동적프록시 기술에 의존하지 않고 프록시를 생성

  • 포인트컷( Pointcut ): 필터링 로직: 어디에 부가 기능을 적용할지, 적용하지 않을지 판단

  • 어드바이스( Advice ):프록시 로직 : 프록시가 호출하는 부가 기능

  • 어드바이저( Advisor ): 단순하게 하나의 포인트컷과 하나의 어드바이스를 가지고 있는 것

  • 포인트 컷은 필터 역할, 어드바이스는 부가기능로직 담당. 둘을 합치면 어드바이저

빈 후처리기

  • 빈 후처리기로 해결된 점 (프록시 생성 부분을 하나로 집중)

    1. 너무 많은 프록시 설정코드
    2. 컴포넌트 스캔으로 프록시 적용이 불가능
  • 프록시 적용 대상을 패키지가 아닌 포인트 컷으로 사용하면 정밀하게 설정

  • AOP는 포인트 컷을 사용

  • 포인트컷 다음 2곳에서 사용

    1. 프록시 적용 대상 여부 체크 꼭 필요한 곳에서만 프록시 적용 (빈 후처리기 - 자동프록시 생성)
    2. 프록시의 어떤 메서드가 호출 되었을 때 어드바이스를 적용할 지 판단 (프록시 내부)
  • AspectJExpressionPointcut: AspectJ AOP에 특화된 포인트컷 표현식

@Aspect

  1. 실행: 로딩 시점에 자동 프록시 생성기 호출
  2. 모든 @Aspect 빈 조회
  3. 어드바이저 생성 : @Aspect 애노테이션 정보를 기반으로 어드바이저 생성
  4. @Aspect 기반 어드바이저 저장: 생성한 어드바이저를 @Aspect 어드바이저 빌더 내부 저장
  • 횡단 관심사 (cross-cutting concerns)의 문제를 해결

스프링 AOP 개념

  • "핵심 기능" "부가 기능"으로 나눔, 여러 곳에서 공통으로 사용하는 부가 기능
  • AOP 소개 - 애스펙트: 애스펙트를 사용한 프로그래밍 방식을 관점 지향 프로그래밍 AOP(Aspect-Oriented Programming)
  • AOP는 OOP의 횡단관심사를 처리하기 위한 보조하는 목적으로 개발
  • AspectJ 프레임워크 -> AOP 대표적인 구현 스프링도 AOP를 지원하지만 AspectJ 문법을 차용

AOP 적용 방식 3가지

  1. 컴파일 시점: AspectJ를 직접 사용
  2. 클래스 로딩 시점: AspectJ를 직접 사용
  3. 런타임 시점: 실제 대상 코드는 유지, 스프링 AOP는 이 방식
  • 스프링은 AspectJ의 문법을 차용하고 프록시 방식의 AOP를 적용하므로 직접 AspectJ를 사용하는 것은 아님 (AspectJ를 사용하면 러닝커브와 자바 관련 설정이 복잡, 스프링 AOP는 실무에서 편리하게 사용가능)

AOP 용어정리

  • 조인 포인트(Join point): 스프링 AOP는 프록시 방식을 사용하므로 조인 포인트는 항상 메소드 실행 지점으로 제한.

  • 포인트컷(Pointcut): 조인 포인트 중에서 어드바이스가 적용될 위치를 선별, 메서드 실행 지점만 선별 가능, 주로 AspectJ 표현식을 사용

  • 타겟(Target): 어드바이스를 받는 객체, 포인트컷으로 결정

  • 어드바이스(Advice): 부가기능, 특정 조인 포인트에서 Aspect에 의해 취해지는 조치

  • 애스펙트(Aspect): 어드바이스 + 포인트컷을 모듈화 한것 '@Asepct'

  • 어드바이저(Advisor): 하나의 어드바이스와 포인트 컷(특별한 애스펙트)

  • 위빙(Weaving): 포인트 컷으로 결정한 타겟의 조인 포인트에 어드바이스를 적용

  • AOP프록시: AOP 기능을 구현하기 위해 만든 프록시 객체( JDK 동적 프록시 or CGLib 프록시)

포인트컷 지시자의 종류

  • execution : 메소드 실행 조인 포인트를 매칭, 스프링 AOP에서 가장 많이 사용

  • within : 특정 타입 내의 조인 포인트를 매칭

  • args : 인자가 주어진 타입의 인스턴스인 조인 포인트

  • this : 스프링 빈 객체(스프링 AOP 프록시)를 대상으로 하는 조인 포인트

  • target : Target 객체(스프링 AOP 프록시가 가르키는 실제 대상)를 대상으로 하는 조인 포인트

  • @target : 실행 객체의 클래스에 주어진 타입의 애노테이션이 있는 조인 포인트

  • @within : 주어진 애노테이션이 있는 타입 내 조인 포인트

  • @annotation : 메서드가 주어진 애노테이션을 가지고 있는 조인 포인트를 매칭

  • @args : 전달된 실제 인수의 런타임 타입이 주어진 타입의 애노테이션을 갖는 조인 포인트

  • bean : 스프링 전용 포인트컷 지시자, 빈의 이름으로 포인트컷을 지정

프록시 내부호출 문제

  • 대안1 자기 자신 주입
  • 대안2 지연 조회
  • 대안3 *구조 변경

프록시 기술과 한계 - 타입 캐스팅

  • JDK 동적 프록시는 대상 클래스 타입으로 주입할 때 문제
  • CGLIB는 대상 클래스에 기본 생성자 필수, 생성자 2번 호출 문제
  • 스프링 3.2, CGLIB를 스프링 내부에 함께 패키징+ 는 final 클래스나 final 메서드를 잘 사용하지는 않으므로 큰 문제X