스프링은 Cross-cutting Concern을 삽입하는 방식에 따라 BeforeAdvice, AfterRetrunningAdvice, AfterThrowingAdvice, AfterAdvice, AroundAdvice 이 5가지로 분류한다. 여기서 Advice는 횡단관심에 해당되는 공통 기능의 코드를 의미한다.

Advice 동작 시점 설명
Before 비지니스 메서드 실행 전 동작
After - AfterReturning : 비지니스 메서드가 성공적으로 리턴되면 동작
- AfterThrowing : 비지니스 메서드 실행 중 예외가 발생하면 동작(마치 try~catch 블록에서 catch 블록에 해당)
- After : 비지니스 메서드가 실행된 후, 무조건 실행(try~catch~finally 블록에서 finally 블록에 해당)
Around Around는 메서드 호출 자체를 가로채 비지니스 메서드 실행 전후에 처리할 로직을 삽입할 수 있음

 

메서드 호출 전후에 수행할 때 사용되는 AroundAdvice를 XML 파일로 설정해보자.

// MethodInterceptor를 구현한 LogAroundAdvice 클래스

package spring.aop.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LogAroundAdvice implements MethodInterceptor{

	@Override
	public Object invoke(MethodInvocation invocation) throws Throwable {
		
		long start = System.currentTimeMillis();
		
		//Around Advice
		Object result = invocation.proceed();
		
		long end = System.currentTimeMillis();
		String message = (end - start) + "ms 시간이 걸렸습니다.";
		
		System.out.println(message);
		
		return result;
	}

}

 

// setting.xml

<?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:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/util
       http://www.springframework.org/schema/util/spring-util-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">
	
	
	<bean id="target" class="spring.aop.entity.NewlecExam" p:kor="1" p:eng="1" p:com="1" p:math="1"/>
	<bean id="logAroundAdvice" class="spring.aop.advice.LogAroundAdvice"/>
	<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="target" />
		<property name="interceptorNames">
			<list>
				<value>logAroundAdvice</value>
			</list>
		</property>
	</bean>
</beans>

 

// main 메서드

package spring.aop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import spring.aop.entity.Exam;
import spring.aop.entity.NewlecExam;

public class Program {

	public static void main(String[] args) {
		
		ApplicationContext context = new ClassPathXmlApplicationContext("spring/aop/setting.xml"); //추가
		
		Exam proxy = (Exam) context.getBean("proxy");
		
		System.out.printf("total is %d\n", proxy.total());
		System.out.printf("avg is %f\n", proxy.avg());
		
	}

}

//출력
//202ms 시간이 걸렸습니다.
//total is 4
//214ms 시간이 걸렸습니다.
//avg is 1.000000

 

참고자료

[1] 유튜브 채널 뉴렉처 - 스프링으로 AOP 구현해보기-AroundAdvice

[2] 티스토리 문코딩 - 웹개발_Back end/2-6 Spring

'🖥️ Backend > Spring' 카테고리의 다른 글

[Spring] 18.Spring AOP(XML, AfterReturningAdvice)  (0) 2024.12.31
[Spring] 17.Spring AOP(XML, BeforeAdvice)  (0) 2024.12.31
[Spring] 15.순수 Java AOP  (0) 2024.12.31
[Spring] 14.@Configuration  (0) 2024.12.30
[Spring] 13.@Component  (0) 2024.12.30
Developer Quarterly