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