AOP : 공통 관심 사항을 구현한 코드를 핵심 코드 안에 삽입하는 방식으로 구현

 - 공통 관심사항 : 공통 기능(전체에 적용)

 - 핵심 관심사항 : 핵심 로직

 

● AOP 용어

 - Advice : 공통 기능을 담은 모듈, 공통 기능을 동작시킬 시점

동작시점 설명
Before 메소드 실행 전에 동작
After 메소드 실행 후에 동작
After-returning 메소드가 정상적으로 실행된 후에 동작
After-throwing 예외가 발생한 후에 동작 (finally 구문)
Around 모든 시점에서 동작

Around Advice의 경우 joinPoint.Proceed()실행 전은 Before Advice, 실행 후는 After- Advice와 같음

Around = Before + After, After-returning ,After-throwing

 

 - JoinPoint : Advice를 적용 가능한 지점 (메서드호출, 필드값 변경 등)

 - PointCut : 실제 Advice가 적용될 JoinPoint, 정규표현식 or AspectJ문법 으로 정의함 / PointCut ⊂ JoinPoint 

 - Weaving : Advice(공통기능)를 핵심 로직에 적용하는 것(행위)

 - Aspect : 어떤 PointCut에 대해 어떤 Advice를 실행할지 결정 / Aspect = Advice + PointCut (가장 큰개념)

 

● AspectJ 문법(PointCut 표현식)

execution([접근자제어패턴], 리턴타입패턴 [패키지패턴] 메서드이름패턴(파라미터패턴))

 - * : 모든값 / ... : 0개 이상

ex) execution(* com.people..*.*(..))

 - 접근자제어 : 생략

 - 리턴타입 : *

 - 패키지 : com.people 패키지와 하위패키지(com.people..)까지 포함한 모든파일       cf) com.people 패키지만 포함할 시 com.people.사용

 - 메서드이름 : *

 - 파라미터 : ..

 

●XML

<aop:config> : AOP 설정

<aop:aspect> : Aspect 설정

 - ref : 공통 기능의 클래스

<aop:pointcut> : PointCut 설정

 - expression : PointCut 표현식

<aop:around> : Around Advice 설정

 - pointcut-ref : 적용할 PointCut, method : 적용할 메서드 (Profiler 클래스의 trace()에 적용)

<bean id="profiler" class="ch07.Profiler" />

<aop:config>
    <aop:aspect id="traceAspect" ref="profiler">
        <aop:pointcut id="publicMethod" expression="execution(public * board..*(..))"/>
        <aop:around pointcut-ref="publicMethod" method="trace"/>
    </aop:aspect>
</aop:config>

Profiler 클래스의 trace()를 publicMethod의 지점에서 Around 시점으로 실행함

 

● 어노테이션

 - xml : <aop:aspectj-autoproxy />

 - config : @EnableAspectJAutoProxy 설정

 

@Aspect : 공통 기능의 클래스(Aspect) 설정

@Pointcut : 적용할 범위(PointCut) 설정

@Around : Around Advice 설정

 ex) @Around("execution(* hello.hellospring..*(..))") : hello.hellospring 패키지 아래의 모든 메서드에 적용

      @Around("@annocation(LogExecutionTime)") : @LogExecutionTime이 붙은 메서드에 적용

      @Around("메서드") : Pointcut을 설정한 메서드

@Aspect
public class ProfilingAspect {

	@Pointcut("execution(public * board..*(..))")
	private void profileTarget() {}
	
	@Around("profileTarget()")
	public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
		String signatureString = joinPoint.getSignature().toShortString();
		System.out.println(signatureString + " 시작");
		long start = System.currentTimeMillis();
		try {
			Object result = joinPoint.proceed();
			return result;
		} finally {
			long finish = System.currentTimeMillis();
			System.out.println(signatureString + "종료 실행 시간 : " + (finish - start) + "ms");
		}
	}
}

 

 

● 구현

 - joinPoint.Proceed() : 핵심 로직을 수행하고 결과값을 Object 타입으로 리턴

 

Spring은 타겟 객체의 프록시를 만들며 호출시 프록시에 먼저접근

그 후, joinPoint.Proceed()를 통해 실제 타겟 객체인 핵심로직 호출

 

 

 

 

'Framework > Spring' 카테고리의 다른 글

Mybatis  (0) 2020.09.18
[JDBC] Mybatis, JPA, Hibernate  (0) 2020.09.18
Spring 메이븐 설정  (0) 2020.09.03
Spring MVC  (0) 2020.08.16
Spring JDBC  (0) 2020.08.02

+ Recent posts