본문 바로가기
Backend boot camp/Session2

Spring Framework Cores(DI/AOP)

by orioncsy 2022. 10. 18.

DI(Dependency Injection)

Spring Container

Spring Container

  • spring framework의 핵심 컴포넌트
  • 내부에 존재하는 애플리케이션 빈의 생명 주기 관리
    • 개발자가 정의한 bean을 객체로 만들어 생성, 제거, 제공 등 관리
    • 원하는 만큼의 객체를 소유
  • public interface ApplicationContext extends ...{}
    • 인터페이스로 구현하고 다형성 적용하여 ApplicationContext로 선언
  • 의존성 주입(DI)으로 애플리케이션 컴포넌트 관리
    • bean을 서로 연결하는 역할
    • 개발자는 의존, 결합 문제에서 자유로움
    • 메서드 호출 시기, 위치, 매개변수 준비하지 않음

Spring Container 사용 목적

  • 객체를 사용하기 위한 new 키워드를 사용하는 단점 보안
    • 참조가 심하여 의존성이 높아 결합성이 높아져 캡슐화에 방해
    • 의존성을 낮추기 위해 spring container 사용
    • 참조) 객체지향 프로그래밍 목표 - 낮은 결합도(의존성)와 높은 응집도(캡슐화)
  • 정책이 변경되거나 추가될 경우 의존성이 높아지는데 이것을 제거하고 인터페이스에 의존시킴

Spring container 생성 방식

  • Spring container는 Configuration Metadata 사용
  • 매개변수로 들어온 설정 클래스 정보에 따라 스프링 빈을 등록
  • new AnnotationConfigApplicationContext(구성정보 클래스)로 bean 등록
  • Java 기반 Annotation 방식
    • ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);
  • XML 방식
    • <beans />에 필요한 값들을 설정
    • <bean id=” …”> 빈의 ‘고유한’ 정의 식별 문자열
    • <bean class=” …”> bean ‘유형’ 정의
  • 스프링 컨테이너를 생성하는 방법 - ApplicationContext 인터페이스 구현체
    • AppConfig.class와 같은 구성 정보를 지정해서 스프링 컨테이너 생성
    • AppConfig에 있는 정보로 필요한 객체 생성
    • 구성 정보 같은 메타데이터와 결합해서 ApplicationConetext 생성, 초기화 후 실행 가능한 애플리케이션
  • 스프링 빈 조회할 때 상속관계가 존재하면 부모 타입 조회하면 자식 타입도 함께 조회
    • object 타입 조회하면 모든 bean 조회
  • ApplicationContext 인터페이스 확인법
    • ctrl + N or cmd + O에서 ApplicationContext 검색

Spring container type

  • Spring Container : 설정 클래스 정보를 참고해서 빈 생성, 관계 설정 제어 역할 총괄
  • BeanFactory
    • Spring Container의 최상위 인터페이스
    • 빈 등록, 생성, 조회, 반환
    • getBean()으로 빈 인스턴스화
    • @Bean이 붙은 메서드명을 빈 이름으로 사용해서 빈 등록
  • ApplicationContext
    • BeanFactory 기능 상속받아 처리
    • BeanFactory가 빈 관리, 검색 기능 / ApplicationContext는 그 외 부가기능
    • ApplicationContext 기능
      • MessageSource 메시지 다국화
      • EnvironmentCapable 개발, 운영을 나누어 처리하고 애플리케이션 필요 정보 관리
      • ApplicationEventPublisher 이벤트 관련 기능
      • ResourceLoader 리소스 조회

New 키워드에 비교한 주입 코드(DI) 특징

  • 생성자에 객체를 주입하여 IoC/DI 구현
  • 의존을 하는 객체에서는 생성자에 어떤 객체가 오는지 알 필요 없음
  • 의존하는 객체는 실행에만 집중
  • 어떤 객체가 오는지는 AppConfig 같은 외부 객체에서 정함

Bean

개념

  • Spring Container에서 관리되는 재사용 소프트웨어 컴포넌트
  • 인스턴스화 된 객체를 의미
  • spring container에 등록된 객체를 spring bean
  • @Bean이 적힌 메서드를 모두 호출해서 반환된 객체를 spring container에 등록
  • Bean에는 등록정보, getter, setter 포함
  • 설정 메타데이터로 컨테이너에서 생성
    • 설정 메타데이터는 XML, java annotation, java로 구현 가능
    • 컨테이너의 명령, 인스턴스화, 설정, 조립 객체 정의

접근 방법

  • ApplicationContext로 객체를 생성한다
  • 생성된 객체에서 getBean() 메서드를 통해 bean 인스턴스 가져옴
  • bean의 인스턴스에서 정보를 가져온다

BeanDefinition

  • BeanDefinition(빈 설정 메타정보)으로 bean을 정의하고 활용
  • 속성에 따라 bean의 생성 관리 결정
  • @Bean이나 <bean>에 1개씩 메타 정보 생성
  • 설정 메타정보를 BeanDefinition 인터페이스를 통해 관리하여 XML, Java로 컨테이너 설정 가능
  • BeanDefinition이 포함하는 메타정보
    • 패키지 수식 클래스 이름 : 빈의 구현 클래스
    • bean동작 구성 요소 : 컨테이너에서 bean 동작 설명(범위, 수명)
    • 다른 bean에 대한 참조
    • 새로 만든 개체에 대한 구성 설정
    • 각 빈 정의를 구성하는 속성 집합
      • BeanClassName - 빈 클래스 명
      • factoryBeanName - 팩토리 역할 빈의 이름
      • factoryMethodName - 팩토리 메서드 지정
      • Scope - 싱글톤
      • lazyInit - 실제 빈을 생성하지 않고 최대한 생성 지연처리 여부
      • InitMethodName - 빈 생성하고 호출한 뒤에 초기화 메서드 이름
      • DestroyMethodName - 생명 주기 끝나 제거하기 전에 호출되는 메서드 이름
      • Constructor arguments, Properties - 의존관계 주입에 사용

Bean Scope

개념

  • bean이 존재할 수 있는 범위
    • 특정 bean 정의에서 생성된 개체에 연결할 의존성과 범위 정의 가능
    • 6개의 범위를 지원, 그중 4개는 ApplicationContext를 사용하는 경우 이용 가능
    • bean 여러 범위 중 하나에 배치
    • 개체의 범위를 선택 가능
    • 사용자 정의 범위도 가능
  • Type
    • singleton - defualt로 단위 객체 인스턴스에 대한 단일 bean definition 범위 지정
    • prototype - 프로토타입 빈의 생성과 의존 관계 주입만 관여
    • request - 웹 요청 들어오고 나가는 스코프
    • session - 세션이 생성, 종료 유지 스코프
    • application - 웹 서블릿 컨텍스와 같은 범위
    • websocket - 단일 bean definition 범위를 WebSocket의 라이프사이클까지 확장, ApplicationContext에서만 유효

Singleton Scope

  • 클래스 인스턴스가 1개만 생성되도록 보장하는 디자인 패턴
  • 컨테이너 시작과 종료까지 유지
  • 싱글톤 빈의 하나의 공유 인스턴스만 관리
    • private으로 외부에서 new를 생성하지 못하도록 방지
  • bean definition과 일치하는 ID를 갖는 빈에 대한 요청은 특정 빈 인스턴스를 반환
  • 컨테이너 종료 시 소멸 메서드 자동 실행
  • 싱글톤 패턴 적용
    • static 객체 인스턴스를 미리 1개 생성
    • 객체 인스턴스가 필요한 경우 getInstance()를 통해 조회만 가능
    • 외부에서 new로 생성자 호출 못하도록 private으로 막는다
  • 싱글톤 패턴의 문제점
    • 구현 코드 다양
    • 클라이언트가 구체 클래스에 의존
    • 지정해서 가져와서 테스트가 어려움
    • private 생성자로 자식 클래스 생성 어려움
    • 속성 공유
      • 멀티 스레드 환경에서 객체 속성 바뀔 수 있음
      • 도중에 바뀌게 되면 잘못된 값을 반환 가능
      • 읽기만 가능해야 함
    • Application 초기 구동에 인스턴스 생성
      • 초기에 싱글톤 빈이 많을수록 구동 시간 증가
  • 싱글톤 패턴의 문제점을 싱글톤 컨테이너가 해결
    • 스프링 컨테이너는 싱글톤 컨테이너 역할
    • 싱글톤 객체로 생성, 관리하는 기능을 싱글톤 레지스트리
    • 스프링 컨테이너가 위의 문제점을 해결하고 싱글톤 유지
    • @Configuration으로 구성정보 담당 설정
    • @Bean을 통해 스프링 컨테이너에 등록
    • static AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.clss)
    • .getBean(”name”, [클래스명.class])로 호출
    • 싱글톤 객체는 무상태로 설계
      • 특정 클라이언트가 값을 변경하면 안 됨
      • 일기만 가능
      • 공유 값 설정하면 오류 발생

Java 기반 컨테이너 설정

@Bean & @Configuration

  • 메서드에 Spring 컨테이너에 관리할 새 객체를 인스턴스화, 구성, 초기화한다는 것을 나타내는 데 사용
@Configuration
public class AppConfig{
	@Bean
	public UserService userService(){
		return new UserService();
	}
}
  • XML 방식
<beans>
	<bean id="userService" class="com.service.UserService"/>
</beans>

AnnotationConfigApplicationContext

  • @Configuration Class
    • 파라미터로 전달받으면 @Configuration class 자체가 bean 정의로 등록되고 클래스 내 모든 @Bean 메서드도 bean정의로 등록
  • @Componenet Class / JSR-330 메타데이터
    • 빈 정의로 등록되고 @Autowired 혹은 @Inject 같은 DI 메타데이터가 사용될 수 있음
    • @Autowired를 사용하면 해당 Type에 따라 자동으로 bean 주입
  • @Configuration class 예제
public static void main(String[] args){
	ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
	UserService userService = ac.getBean(UserService.class);
}
  • @Component Class / JSR-330 메타데이터 예제
public static void main(String[] args){
	ApplicatgionContext ac = new AnnotaitonConfigApplicationContext(UserService.class, Dependency1.class)
	UserService userService = ac.getBean(UserService.class);
}

@Bean 사용

  • 메서드 레벨 애너테이션으로 <bean/>에서 제공하는 속성 제공
  • init-method
  • destroy-method
  • autowiring
  • Bean 선언
    • @Configuration과 @Bean 선언하여 구현
    • XML에서 </beans> 안에 <bean id=”…” class=”..”>로 구현
    • 빈 정의가 있는 인터페이스를 구현하고 @Configuration과 implements을 선언하여 구현
    • @Bean 객체의 이름은 메서드 이름으로 저장됨

@Configuration 사용

  • bean definition의 소스임을 나타내는 애너테이션
  • @Bean-annoted 메서드를 통해 bean 생성
  • @Bean 메서드 호출 bean 사이 의존성 정의
  • Bean 사이의 의존성 주입/java 기반으로 설정된 환경에서 내부적으로 작동하는 방식 정보

Java에서 Spring container 구성

  • @Import(Config.class)
    • XML 파일 내 요소 사용처럼 모듈화 하는 데 사용
    • 다른 구성 클래스에서 @Bean definitions를 가져올 수 있음

Component Scan

Component scan

  • 설정 정보 없이 자동으로 빈 등록
  • @ComponentScan은 @Component가 붙은 모든 클래스를 스프링 빈으로 등록
  • 의존 관계에서 자동으로 주입하는 @AutoWired 기능 제공

사용 방법

  • @Configuration에 @Component가 있기 때문에 @ComponentScan으로 자동으로 빈 등록 가능
  • 기존 @Configuration 설정이 된 파일 있을 때
    • @ComponentScan(excludeFilters = @Filter(type = FilterType.ANNOTATION, classes = Configuration.class)) 추가
  • XML 방식 component scan
<beans>
	<context:component-scan base-package="com.acme"/>
</beans>

@Component & @Autowired

  • 클래스 앞에 @Component 선언하여 @ComponentScan에서 해당 객체를 가져올 수 있음
  • @Autowired를 사용하여 생성자 의존성 주입에 필요한 설정 정보 대신 의존관계 자동 주입

basePackages

  • 탐색할 패키지의 시작 위치 지장, 하위 패키지까지 모두 탐색
  • @ComponentScan()의 매개변수로 basePackages=””지정 가능
  • 지정을 안 하면 @ComponentScan이 붙은 설정 정보 클래스 패키지가 시작 위치
  • @SpringBootApplication을 프로젝트 시작 위치에 두는 것도 가능
    • @SpringBootApplication안에 @ComponentScan이 존재

Component Scan 대상

  • @Component - 컴포넌트 스캔 대상
  • @Controller & @RestController - 스프링 MVC, REST 전용 컨트롤러
  • @Service - 스프링 비즈니스 로직에 사용
    • 특별한 처리 없이 핵심 비즈니스 로직이라는 것을 알리기 위해 사용
  • @Repository - 스프링 데이터 접근 계층에서 사용
    • 데이터 접근 계층으로 인식하고 데이터 계층 예외를 스프링 예외로 변환
  • @Configuration - 스프링 설정 정보에서 사용
    • 스프링 설정 정보로 인식, 스프링 빈이 싱글 톤 유지하도록 추가 처리

필터

  • includeFilters - 컴포넌트 스캔 대상 추가
  • excludeFilters - 컴포넌트 스캔 제외
  • FilterType 옵션
    • ANNOTATION - 기본값
    • ASSIGNABLE_TYPE - 지정 타입, 자식 타입 인식
    • ASPECTJ - AspectJ 패턴 사용
    • REGEX - 정규 표현식
    • CUSTOM - TypeFilter 인터페이스 구현 처리

의존관계 주입 방식

1. 생성자 주입

  • 생성자를 통해서 의존관계를 주입하는 방식
    • 생성자에 @Autowired를 하면 @Component로 등록된 빈에서 생성자에 필요한 빈 주입
  • 생성자 호출 시점 1번만 호출
  • 불변과 필수 의존 관계에서 사용
  • 생성자가 1개만 존재하는 경우 @Autowired 생략 가능
  • NullPointerException 방지
  • 주입받을 필드 final로 선언 가능

2. 수정자 주입(setter 주입)

  • setter라 불리는 필드의 값을 변경하는 수정자를 통해 의존 관계 주입
  • 선택과 변경 의존 관계에서 사용
  • 자바 빈 프로퍼티 규약의 수정자 메서드 방식 사용
  • Autowired롤 입력해야 한다

3. 필드 주입

  • 필드에 @Autowired를 붙여서 바로 주입하는 경우
  • 외부에서 변경 불가하고 테스트 어려움
  • 실제 코드와 상관없는 특정 테스트할 때 사용
  • 정상 작동을 위해 setter가 필요하다

4. 일반 메서드 주입

  • 일반 메서드에 주입
  • 한 번에 여러 필드를 주입받는 것 가능
  • 일반적으로 사용 안 함

옵션 처리

  • 주입할 스프링 빈이 없을 때 동작하게 하기 위한 처리
  • 스프링 빈을 옵셔널로 해두고 사용
  • @Autowired(required=false) - 자동 주입 대상 없으면 수정자 메서드 자체가 호출 안됨
  • org.springframework.lang.@Nullable - 자동 주입 대상 없으면 null 입력
  • Optional <> - 자동 주입 대상이 없으면 Optional.empty 입력

생성자 주입을 사용하는 이유

  • 불변
    • 의존 관계 주입은 종료 때까지 변경되지 않고 변경되면 안 된다
    • 수정자 주입은 이름 메서드를 public으로 열어서 변경 가능해서 부적합
    • 생성자 주입으로 객체 생성할 때 1번만 호출하고 그 이후에 변경하지 않아 불변 구현 가능
  • 누락
    • 호출했을 때 NPE 발생 가능한데 의존관계 주입 누락되어서 발생
    • 생성자 주입을 사용하면 컴파일 오류로 발생
  • final 키워드 사용 가능
    • 생성자 이외의 주입 방식은 생성자 호출 이후에 부르기 때문에 final 키워드 사용 불가
    • 생성자에서 값이 설정되지 않으면 컴파일 오류
  • 순환 참조
    • 순환 참조 방지
    • 여러 컴포넌트 간에 의존성이 생기고 A→B , B→A로 참조 가능
    • 다른 주입 방식은 빈 생성 이후 호출되기 때문에 오류 발생이 없다
    • 생성자 주입은 BeanCurrentlyInCreationException 발생

생성자 주입 방식 장점

  • 의존 관계 설정이 안 되면 객체 생성 불가
    • 컴파일 에러로 확인 가능
    • NPE 방지
  • final로 선언 가능
  • 순환 참조 감지 가능
  • 테스트 코드 작성 용이
  • 수정자 주입은 옵션이 필요할 때만 선택

AOP(Aspect Oriented Programming)

Aspect

  • 부가 기능과 그 기능들을 어디에 적용할지 선택하는 기능을 합한 하나의 모듈
  • 애플리케이션을 바라보는 관점을 기능을 바라보는 관점, 즉 횡단 관심사(cross-cutting concerns)

AOP

등장 배경

  • OOP만 구현해서는 비즈니스 코드에서 관심사 분리(Seperation of Concerns, SoC)를 하여 횡단 관심사 코드를 분리하기 어려워 AOP 등장

개념

  • 객체 중심으로 구현하는 OOP의 단점을 보완하기 위해 관점을 분리하고 여러 유형과 객체 간 발생 문제를 모듈화가 가능하게 한다
  • 객체마다 존재하는 공통 부가 기능들을 따로 분리하여 적용함으로써 불필요한 코드 반복을 최소화

구성

  • 핵심 기능(Core Concerns) : 객체가 제공하는 고유 업무 로직 담당
  • 부가 기능(Cross-cutting Concerns) : 핵심 기능을 도와주는 역할
    • 단독으로 사용하지 않고 핵심 기능과 함께 사용
    • 여러 클래스에 걸쳐 적용되어 cross-cutting concerns(횡단 관심사)로 존재
    • 보안, 트랜잭션, 로깅
  • 객체 안에 핵심 기능, 부가 기능이 합쳐져 하나의 로직으로 실행

관련 용어

  • Aspect
    • 여러 객체에 공통으로 적용되는 기능(cross-cutting concerns)
    • Advice + PointCut
      • Advice - 부가 기능 정의
      • PointCut - 부가 기능을 어디에 적용할지 결정
  • Join point
    • 애플리케이션 실행 흐름에서 특정 포인트 지칭
    • AOP를 적용할 수 있는 모든 지점을 지칭
    • 새로운 동작을 추가하기 위해 join point에 aspect code 추가 가능
    • Spring AOP는 프록시 방식 사용 - join point는 메서드 실행 지점으로 제한
    • 어드바이스 적용이 필요한 곳은 메서드 존재
  • Advice
    • join point에서 수행되는 부가 기능 코드
    • Aspect를 언제 핵심 코드에 넣을지 정의
    • 전체 aspect에 API 호출 제공
    • 메서드 호출 전 로그로 남기기 위해 시작 전 조인 포인트를 선택
  • PointCut
    • join point 중에 advice가 적용될 위치 선별
    • AspectJ 표현식으로 지정
    • 프록시를 사용하는 Spring AOP에서는 메서드 실행 지점만 선별 가능
  • Weaving
    • PointCut으로 결정된 join point에 advice 적용하는 것
    • 핵심 코드에 영향을 주지 않고 부가 기능 추가
    • AOP 적용을 위해 객체 연결
      • 컴파일 타임(AspectJ compiler), 로드 타임, 런타임
  • AOP proxy
    • AOP 구현을 위해 만든 proxy 객체
    • Spring AOP에서는 JDK 동적 프록시, CGLIB 프록시
  • Target
    • 핵심 기능을 담고 있는 모듈
    • 부가 기능 부여 대상
    • Advice 받는 객체이고 pointCut으로 결정
  • Advisor
    • 하나의 advice와 하나의 pointCut으로 구성

Advice

순서

  • 기본적으로 순서를 보장하지 않음
  • 순서를 지정하기 위해서 @Aspect 적용 단위로 org.springframework.core.annotation.@Order 적용
    • 클래스 단위로 적용
    • 여러 advice가 존재하면 순서 보장 안됨
  • aspect를 별도의 클래스로 분리

종류

  • Before
    • join point 이전에 실행
    • 타깃이 실행되기 전 공통 기능을 실행
    • 리턴 타입이 void
    • 메서드에서 예외 발생할 경우 메서드 호출하지 않음
  • After returning
    • join point 정상 완료 후 실행
    • 메서드 실행 후 공통 기능 실행
    • returning 속성에 사용된 이름은 메서드 매개변수 이름과 일치
    • returning 절에 지정된 타입을 반환하는 메서드만 대상
  • After throwing
    • 메서드가 예외를 던지는 경우 공통 기능 실행
    • throwing 속성에 사용된 이름이 메서드 매개변수 이름과 일치
    • throwing 절에 지정된 타입과 맞는 예외를 대상으로 실행
  • After (finally)
    • join point 작동과 상관없이 공통 기능 실행
    • 리소스 해제할 때 사용
  • Around
    • 메서드 전후, 예외 발생 시점에 수행
    • joinPoint.proceed() - 조인 포인트 실행 여부
    • joinPoint.proceed(args[]) 전달 값 변환
    • 반환 값 변환
    • 예외 변환
    • try - catch - finally 구문 처리 가능
    • 첫 번째 파라미터는 ProceedingJoinPoint 사용
    • proceed()를 통해 대상 여러 번 실행 가능

Pointcut 표현식

  • 관심 조인 포인트를 결정하여 어드바이스 실행 시기 제어
  • AspectJ가 제공하는 pointcut expression

포인트 컷 지시자 종류

  • execution - 메서드 실행 조인 포인트 매칭
  • within - 특정 타입 내 조인 포인트 매칭
  • args - 인자가 주어진 타입의 인스턴스 조인 포인트
  • this - 스프링 빈 객체를 대상으로 하는 조인 포인트
  • target - target 객체를 대상으로 하는 조인 포인트
  • @target - 실행 객체의 클래스에 주어진 타입의 애너테이션이 있는 조인 포인트
  • @within - 주어진 애너테이션이 있는 타입 내 조인 포인트
  • @args - 인수로 주어진 타입의 애너테이션을 갖는 조인 포인트
  • bean - 스프링 전용, 빈의 이름으로 포인트 컷 지정

Pointcut 표현식 결합

  1. anyPublicOperation - 메서드 실행 조인 포인트가 공용 메서드 실행을 나타내는 경우 일치
  2. inTrading - 메서드 실행이 거래 모듈에 있는 경우 일치
  3. tradingOperation - 메서드 실행이 거래 모듈의 공개 메서드를 나타내는 경우 일치

일반적인 pointcut 표현식들

  • execution(public * *(..))
    • 모든 공개 메서드 실행
  • execution(* set*(..))
    • set 다음으로 시작하는 모든 메서드 실행
  • execution(* com.xyz.service.AccountService.*(..))
    • AccountService 인터페이스에 의해 정의된 모든 메서드의 실행
  • execution(* com.xyz.service.*.*(..))
    • service 패키지에 정의된 메서드 실행
  • execution(* com.xyz.service..*.*(..))
    • service 패키지 또는 하위 패키지 중 하나에 정의된 메서드 실행
  • within(com.xyz.service.*)
    • service 패키지 내 모든 조인 포인트
  • within(com.xyz.service..*)
    • service 패키지 또는 하위 패키지 중 하나 내 모든 조인 포인트
  • this(com.xyz.service.AccountService)
    • AccountService 프록시가 인터페이스 구현하는 모든 조인 포인트
  • target(com.xyz.service.AccountService)
    • AccountService 대상 객체가 인터페이스를 구현하는 모든 조인 포인트
  • args(java.io.Serializable)
    • 단일 매개변수 사용하고 런테임에 전달된 인수가 Serializable과 같은 모든 조인 포인트
  • @target(org.springframework.transaction.annotation.Transactional)
    • 대상 객체에 @Transactional 이 있는 모든 조인 포인트
  • @annotation(org.springframework.transaction.annotation.Transactional)
    • 실행 메서드에 @Transactional이 있는 조인 포인트
  • @args(com.xyz.security.Classified)
    • 단일 매개변수에 전달된 인수의 런타임 유형이 @Classified를 갖는 조인 포인트
  • bean(tradeService)
    • tradeService라는 이름을 가진 스프링 빈의 모든 조인 포인트
  • bean(*Service)
    • 와일드 표현식, *Service라는 이름을 가진 스프링 빈의 모든 조인 포인트

Join Point

적용 위치

  • AOP 적용 위치 - 생성자, 필드 값 접근, static 메서드 접근, 메서드 실행
  • AOP 수행하는 메서드는 joinpoint 인스턴스를 인자로 받는다
  • joinpoint 인스턴스에서 joinpoint 지점 정보 획득

특징

  • AspectJ를 사용해서 컴파일 시점과 클래스 로딩 시점에 적용하는 AOP는 바이트 코드를 조작하여 모든 지점에 적용 가능
  • 프록시 방식을 사용하는 스프링 AOP는 메서드 실행 지점에만 적용 가능
  • 스프링 빈에만 AOP 적용 가능
  • 프록시는 메서드 오버라이딩 개념으로 동작
  • 생성자, static 메서드, 필드 값 접근에 프록시 개념 불가
  • 어드바이스 메서드에 매개변수로 선언

JoinPoint 인터페이스 기능

  • JoinPoint.getArgs() - 전달된 인자 배열로 반환
  • JoinPoint.getThis() - AOP 프록시 객체를 반환
  • JoinPoint.getTarget() - AOP 적용 대상 객체(비즈니스 객체) 반환
  • JoinPoint.getSignature() - 설명을 반환
    • 클라이언트가 호출한 메서드의 시그니처 정보를 Signature 객체로 반환
    • Signature
      • String getName(), String toLongString(), String toShortString()
  • JoinPoint.toString() - 설명 출력

ProceedingJoinPoint 인터페이스

  • proceed() - 다음 어드바이스나 타깃 호출

Annotation을 활용한 AOP

@AspectJ

  • 일반 java 클래스에 애너테이션으로 관점 선언하는 스타일
  • 스프링은 AspectJ가 제공하는 라이브러리를 사용하여 애너테이션 해석
  • AOP 런타임은 순수 스프링 AOP

사용

  • 자동 프록시 빈에 대한 spring 지원 활성화하기
  • XML
  • <aop:aspectj-autoproxy/>
  • Java
  • @Configuration @EnableAspectJAutoProxy public class AppConfig{ ... }

Aspect 선언

  • XML
<bean id="userAspect" class="...">
	...
</bean>
  • Java
import org.aspectj.lang.annotation.Aspect;
@Aspect
public class [className]{
...
}

Pointcut 선언

  • 어드바이스 실행되는 시기 제어
  • Spring Bean의 메서드 실행과 일치
  • 이름과 매개변수 포함하는 signature와 메서드 실행 결정하는 표현식으로 구성
  • @Pointcut으로 표시

Advice 선언

  • 포인트 컷과 일치하는 메서드 실행 전후에 실행

'Backend boot camp > Session2' 카테고리의 다른 글

KPT 회고  (1) 2022.10.19
Technical interview  (1) 2022.10.18
Spring Framework Basics  (1) 2022.10.18
Relational DataBase  (0) 2022.10.03
REST API  (0) 2022.10.03