Java

[Spring]💨 AOP(Aspect Oriented Programming)와 애노테이션(Annotation)

Jimyeung 2021. 10. 7. 22:26
728x90

💨AOP(Aspect Oriented Programming)


💨1.AOP

  • 사용자가 요구했던 업무족인 내용이라기보다 개발자나 관리자가 프로그램을 위해 필요한 코드들을 추가(주 업무로직X- 사용자도 모름)
  • 객체지향보다 더 큰 범위

🔒🔑기존방식

  • 로그를 처리하겠다 할대 직접 코드를 열여서 직접 위아래 입력하고 주석하고 풀고 이런 귀찮은 잃을 해야함
  • 소스코드가 있는 사람만 cross-cutting해당사항 넣었다 뺄 수 있음

🔑aop로 보완

  • 꽂아져 있지않지만 꽂아져 있는것처럼 구현
  • 가운데 부분에 proxy 생성
  • 위 사진 화살표로 흐름 파악
  • spring 사용시 더욱 더 쉽게 개발 가능

💨2. AOP 환경설정

  • ✅pom.xml에 필요한 library들 설치( /build 와 /project사이에 넣어준다.)
<dependencies>
       <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>4.3.30.RELEASE</version>
       </dependency>

       <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.20</version>
     </dependency>

          <!-- AOP 적용시에 필요한 추가 library
            - byte code를 실시간 동적으로 자동 생성해주는 기능의 library
         -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!-- AOP 기능의 framework
            - spring이 AOP 기술을  활용해서 spring 스럽게 활용
         -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.7.3</version>
        </dependency>

  </dependencies>
  • ✅aop.xml의 Namespaces에서 필요한 스펙들 추가해준다(aop, **beans, context)

  • aop.xml의 source에서 애노테이션을 사용하겠다는 설정과 어느 페키지를 스캔할것인지에 대한 설정을 해준다

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">

    <!-- aop사용을 위한 필수 설정 -->
    <aop:aspectj-autoproxy/>

    <!--  annotation 사용하겠다는 설정 -->
    <context:annotation-config/>

    <context:component-scan base-package="common"/>
    <context:component-scan base-package="step02.aop.biz"/>
</beans>

3. 예제를 통한 이해

@Aspect //apsect로 사용된다는 @Asepct 애노테이션 사용 @Component //빈 객체로 생성 public class NoticeAspect {

// @Before("execution(\* step02.aop.biz.Car.buy\*(..))")  
public static void beforeNotic() {  
System.out.println("common 1 - 구매를 하실건가요?");  
}

// @After("execution(\* step02.aop.biz.Car.buy\*(..))")  
public static void afterNotic() {  
System.out.println("common 2 - 구매 완료 하셨습니다.");  
}

// @AfterThrowing(pointcut="execution(\* step02.aop.biz.Car.sell\*(int))", throwing="e" )  
public void noticException(Exception e) {  
System.out.println(e.getMessage());  
}

// @AfterReturning(pointcut="execution(\* step02.aop.biz.Car.\*(..))", returning = "v")  
public void noticReturnValue(Object v) {  
System.out.println("biz가 리턴한 데이터값은 - " + v);  
}

@Around(value = "within(step02.aop.biz.Car)")
public Object aroundCommon(ProceedingJoinPoint point ) {
    System.out.println("around : common 1 - 구매를 하실건가요?"); //before

    Object v = null;
    try {
         v = point.proceed(); // 실제 호출한 biz 메소드 실행
         System.out.println("biz가 리턴한 데이터값은 - " + v);
    } catch (Throwable e) {
        System.out.println(e.getMessage());


// e.printStackTrace();  
}


    System.out.println("around : common 2 - 구매 완료 하셨습니다.");//after & after returning, 후처리
    return v;  //핵심로직 실행 결과값 반환
}

}

간단한 애노테이션 설명

  • @Before("execution(* step02.aop.biz.Car.buy*(..))") - biz 실행 전 공통 로직의 애노테이션
  • @After("execution(* step02.aop.biz.Car.buy*(..))") - biz 실행 후 공통 로직의 애노테이션
  • @AfterThrwoing(pointcut="execution(* step02.aop.biz.Car.sell*(int))", throwing="e" ) - 에외 발생시 처리 애노테이션
  • @AfterReturning(pointcut="execution(* step02.aop.biz.Car.*(..))" - biz 메소드 반환값이 있을 경우 반환하는 애노테이션
  • @Around(value = "within(step02.aop.biz.Car)") - before & after & throwing & returning 조합된 애노테이션

출처:https://www.youtube.com/watch?v=eHYPujubB3E&list=PLq8wAnVUcTFUHYMzoV2RoFoY2HDTKru3T&index=21