ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 스프링 AOP (스프링 핵심 기술 - 5)
    Programming/Spring Framework 주요 개념 2020. 3. 5. 00:43
    728x90

     

    1. AOP (Aspect-Oriented Programming) 이란?

    - OOP를 보완하는 수단으로, 흩어진 Aspect를 모듈화 할 수 있는 프로그래밍 기법

    - 흩어진 관심사들을 하나로 모아서 Aspect로 모듈화하는 기법

     

     

    2. 주요 개념

    - Aspect : 모듈

    - Target : 적용되는 대상 (Class A, B)

    - Advice : 해야할 일

    - Join Point : 합류 지점 (생성자 호출 전, 메소드를 호출하기 전, 필드에서 값을 가져갈 때...)

    - Pointcut : 어디에 적용되어야 하는지

     

     

    3. 구현체

    - AspectJ (다양한 Join Point를 사용해야 할 때)

    - 스프링 AOP

    - 둘을 연동해서 사용 가능

     

     

    3. 적용 방법

    - 컴파일 타임 : 컴파일 할 때, 조작된 자바 바이트 코드를 생성 (AspectJ 컴파일러)

    - 로드 타임 : 바이트 코드를 로드할 때 생성 (AspectJ 사용)

    - 런타임 : A객체 빈을 만들 때, 이를 감싸는 proxy 빈을 만듬 (스프링 AOP 사용 - 합리적이고, 자주 쓰게될 방법)

     

     

    4. 스프링AOP

    - 프록시 기반의 AOP 구현체

    - 스프링 빈에만 AOP를 적용할 수 있다

     

    프록시 패턴

    - 왜 프록시 패턴 사용? 기존 코드 변경 없이 접근 제어 또는 부가 기능 추가

    - Proxy는 RealSubject를 참조하며 이 기능 + 추가적인 기능을 수행함.

    - Client와 RealSubject 코드의 변경없이 기능 추가

    - 매번 프록시 클래스 생성, 객체들 관계 복잡 등 문제 있음 따라서 스프링 AOP 등장

     

    스프링AOP

    - 스프링 IoC컨테이너가 제공하는 기반 시설과 Dynamic 프록시를 사용하여 복잡한 문제 해결

    - 동적 프록시 (동적으로 프록시 객체를 생성)

    - 스프링 IoC의 AbstractAutoProxyCreator(BeanPostConstruct를 상속)는 기존 빈을 대체하는 동적 프록시 빈을 만들 어 등록 시켜줌

     

     

    5. @AOP

    - 어노테이션 기반의 @AOP 

     

    1. 의존성 추가

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-aop</artifactId>
    </dependency>

     

    2. Aspect 정의

    @Component
    @Aspect
    public class PerfAspect {
    
        // 어디에 적용할 것인가 (포인트 컷)
        @Around("@annotation(PerfLogging)")
        // 해야할 일 (어드바이스)
        public Object logPerf(ProceedingJoinPoint pjp) throws Throwable {
            // pjp 는 적용되는 부분으로 (메소드 그 자체)
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed();
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }
    
        @Before("bean(simpleEventService)")
        public void printHello(){
            System.out.println("Hello~");
        }
    
    }
    

     

    3. 어노테이션 정의

    /*
        이 어노테이션을 사용하면 성능을 측정해줍니다.
     */
    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface PerfLogging {
    }
    

     

     

    참고)

    // 인터페이스 타입인 경우 인터페이스로 주입 받는 것을 권장함
    
    @Autowired
    EventService eventService;
    
    /*
    실무에서 우려되는 부분은
    인터페이스를 쓰지 않을 때 다음과 같은 복잡한 문제가 생길 수 있음
    
    인터페이스를 기반으로 프록시 객체를 만들도록 설정하면
    MyService -> DefaultMyService
    MyService -> ProxyService
    ProxyService 는 DefaultMyService 와 상속관계가 아니므로 불러올 수 없음
    
    스프링 부트는 default로 클래스를 기반으로 프록시 객체를 만듬
    MyService -> DefaultMyService -> ProxyService
    */
    // 이렇게 같은 타입으로 지정하거나, 같은 클래스 이름으로 지정하면 해당 빈을 주입받을 수 있음
    
    @Autowired
    SimpleEventService simpleEventService;
    
    @Autowired
    EventService simpleEventService;

     

     

    인프런 백기선님 '스프링 프레임워크 핵심 기술' 강의를 듣고 정리한 내용입니다.

     

    728x90

    댓글

Designed by Tistory.