스프링 프레임워크 핵심 기술 - 스프링 AOP, Null-Safety, 마무리

 

스프링 프레임워크 - 스프링 AOP, Null-Safety, 마무리

지난 강의 정리

ApplicationContext는 단순히 BeanFactory의 기능만 하는 것이 아니고 ResourceLoader, ApplicationEventPublisher,MessageSource, Environment 등 여러 기능들이 있습니다.

스프링 AOP

스프링 AOP - 개념 소개

Aspect-oriented Programming (AOP)은 OOP를 보완하는 수단으로 흩어진 Aspect를 모듈화 할 수 있는 프로그래밍 기법입니다.

스크린샷 2020-11-30 오후 11 05 26

스크린샷 2020-11-30 오후 11 05 32

흩어진 관심사(Crosscutting Concerns)

Concerns은 여러 클래스에서 비슷하게 쓰이는 코드

트랜잭션, 로깅 등…

AOP는 무엇일까?

해야할 일(관심사; 특정 기능)과 적용할 곳을 한 곳으로 모아서 모듈화(Aspect)를 하는 것입니다.

AOP 주요 개념
  • Advice: 해야할 일 - 언제 공통 관심 기능들을 핵심 로직에 적용할지 정의

  • Target: 적용이 되어야할 대상

  • Join Point: 합류 지점(끼어들 수 있는 곳)

  • Pointcut: 적용할 곳

  • Weaving: Advice를 핵심 로직 코드에 적용하는 것을 위빙

AOP 구현체
  • AspectJ
  • 스프링 AOP
AOP 적용 방법
  • 컴파일
    • 컴파일할 때(바이트 코드) 함께 적용을 하는 방법
  • 로드 타임
    • 클래스 A는 이미 컴파일이 되어있고 JVM에서 로드 될 때 Aspect가 같이 로드 되는 방법
  • 런타임
    • A라는 빈에 Aspect X를 적용해야 하는 것을 스프링이 알고 있고, A 타입의 프록시 빈을 만들어서 실제 A의 메서드를 호출하기 전에 Aspect X를 적용하고 A를 호출하는 방법

스프링 AOP - 프록시 기반 AOP

스프링 AOP 특징
  • 프록시 기반의 AOP 구현체입니다.
  • 스프링 빈에만 AOP를 적용할 수 있습니다.
  • 모든 AOP 기능을 제공하는 것이 목적이 아닌, 스프링 IoC와 연동하여 엔터프라이즈 애플리케이션에서 가장 흔한 문제에 대한 해결책을 제공하는 것이 목적입니다.
프록시 패턴

스크린샷 2020-11-30 오후 11 18 20

프록시 패턴을 사용하는 이유

프록시 패턴은 기존 코드 변경 없이 어떤 객체에 대한 접근을 제어하는 용도 및 부가 기능을 추가하여 클라이언트에게 해당하는 객체를 제공하는 패턴입니다.

프록시 패턴의 문제점
  • 결국 중복 코드가 생길 수 밖에 없고, 프록시 클래스를 만드는 비용이 들 수 있습니다.
  • 같은 기능을 여러 클래스, 여러 메소드에 적용하려면 또 프록시를 만들고 중복된 작성할 수 밖에 없는 문제가 있습니다.
스프링 AOP
  • 스프링 IoC 컨테이너가 제공하는 기반 시설과 dynamic 프록시를 사용하여 문제를 해결할 수 있습니다.
  • 동적(Dynamic) 프록시: 동적으로 프록시를 만들어주는 방법
  • 스프링 IoC: 기존 빈을 대체하는 동적 프록시 빈을 만들어 등록시켜 주는 역할을 합니다.
    • 클라이언트의 코드 변경이 없습니다.
    • AbstractAutoProxyCreator implements BeanPostProcessor

스프링 AOP: @AOP

애노테이션 기반의 스프링 @AOP

의존성 추가
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
Aspect 정의
@Component
@Aspect
public class TestAspect {

    //@Arround("execution(* com.yoon..*.EventService.*(..))") // EventService 아래 모든 메서드 적용
    @Arround("@annotation(PerfLogging)")
    public Object logTest(ProceedingJoinPoint pjp) throws Throwable {
        long begin = System.currentTimeMillis();
        Object retVal = pjp.proceed();
        System.out.println(System.currentTimeMills() - begin);
        return retVal;
    }
}

execution으로 클래스 범위를 정할 수 있으나 메서드 단위로 사용하기 어렵습니다.

@annotation 방식

특정 메서드에 추가할 때 annotation 방식을 사용합니다.

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.CLASS)
public @interface PerfLogging {
}

Aspect를 적용할 메서드에 @PerfLogging 애너테이션을 붙여줍니다.

bean으로 적용하는 방식
@Arround("bean(simpleEventService)")
어드바이스 정의
  • @Before - 대상 Method가 실행되기 전에 호출
  • @AfterReturning - 대상 Method가 정상적으로 실행된 이후 호출
  • @AfterThrowing - 대상 Method가 예외를 발생시킨 경우 호출
  • @After - 대상 Method가 정상적이건 예외건 상관없이 호출
  • @Arround - 대상 Method에 대한 호출 자체를 가로챔, 위 4가지 경우 가능

Null-Safety

툴의 지원을 받아 컴파일 타임에 최대한 NullPointerException을 방지하기 위해 사용하는 애너테이션 입니다.

Null 관련 애너테이션
  • @NonNull
  • @Nullable
  • @NonNullApi
  • @NonNullFields
인텔리제이 사용시

Preferences -> Build,Excecution,Deployment -> Compiler -> Add runtime assertions for non-null ~ 체크 configure -> org.springframework.lang 패키지의 NonNull, Nullable 추가

마무리…

스프링 프레임워크의 핵심 기술에 대하여 간략하게 학습할 수 있었던 강의 였습니다. 스프링 IoC의 개념과 여러 기능들을 쭉 훑어 볼 수 있었습니다.