AOP는 메서드 안의 주기능과 보조 기능을 분리한 후 선택적으로 메서드에 적용해서 사용한다는 개념이다.
일단 보조 기능을 만들어 놓고 원할 때 설정 한번으로 부품을 가져다 쓰듯이 사용하면 된다는 뜻이다. 당연히 코드가 단순해지고 가독성이 좋아질 수 밖에 없다.
AOP의 장점
- 전체 코드에 흩어져 있는 보조 기능을 하나의 장소에 모아서 관리
- 코드가 단순해지고 가독성이 향상
여러가지 AOP 관련 용어
용어 | 설명 |
aspect | 구현하고자 하는 보조 기능을 의미함 |
advice | aspect의 실제 구현체(클래스)를 의미, 메소드 호출을 기준으로 여러 지점에서 실행됨. |
joinpoint | advice를 적용하는 지점을 의미, 스프링은 method 결합점만 제공. |
pointcut | advice가 적용되는 대상을 지정, 패키지 이름/ 클래스 이름/ 메소드 이름을 정규식으로 지정하여 사용 |
target | advice가 적용되는 클래스 의미 |
weaving | advice를 주기능에 적용하는 것을 의미 |
스프링 프레임워크에서 AOP 기능을 구현하는 방법
스프링 프레임워크에서 AOP 기능을 구현하는 방법으로는 스프링 프레임워크에서 제공하는 AOP관련 API를 이용하는 방법과 애너테이션을 이용하는 방법이 있다.
1) 스프링 프레임워크에서 제공하는 API이용 방법
스프링 API에서 제공하는 여러가지 Advice 인터페이스
인터페이스 | 추상 메서드 | 설명 |
MethodBeforeAdvice | void before(Method method, Object[] args, Object target) throws Throwable |
해당 메서드가 실행되기 전 실행 |
- Method method : 대상 객체에서 실행된 메서드를 나타내는 메서드 객체 - Object[] args : 메서드 인자 목록 - Object target : 대상 객체 |
||
AfterReturningAdvice | void afterReturning( Object returnValue, Method method, Object[] args, Object target) throws Throwable |
해당 메서드가 실행된 후 수행 |
- Object returnValue : 대상 객체의 메서드가 반환하는 값 - Method method : 대상 객체에서 실행된 메서드를 나타내는 메서드 객체 - Object[] args : 메서드 인자 목록 - Object target : 대상 객체 |
||
ThrowsAdvice | void afterThrowing( Method method, Object[] args, Object target, Exception ex) |
해당 메서드에서 예외 발생 시 실행 |
- Method method : 대상 객체에서 실행된 메서드를 나타내는 메서드 객체 - Object[] args : 메서드 인자 목록 - Object target : 대상 객체 - Exception ex : 발생한 예외 타입 |
||
MethodInterceptor | Object invoke( MethodInvocation invocation) throws Throwable |
해당 메서드의 실행 전/후와 예외 발생 시 실행 |
- MethodInvocation invocation : 대상 객체의 모든 정보를 담고 있는 객체 (호출된 메서드, 인자 등) |
이 중 MethodInterceptor는 invoke() 메서드를 통해 다른 세 가지 인터페이스들의 동시에 수행할 수 있음
2) @Aspect 애너테이션을 이용하는 방법
AOPTest.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans
PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<!-- 타겟 클래스 빈을 지정 -->
<bean id="calcTarget" class="com.spring.ex01.Calculator" />
<!-- 로그 기능을 하는 어드바이스 빈을 지정 -->
<bean id="logAdvice" class="com.spring.ex01.LoggingAdvice" />
<!-- 타겟에 어드바이스를 설정 -->
<bean id="proxyCal" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="calcTarget" />
<property name="interceptorNames">
<list>
<value>logAdvice</value>
</list>
</property>
</bean>
</beans>
<bean> 태그를 통해 타깃 빈과 어드바이스 빈을 생성한 후 스프링의 ProxyFactoryBean 클래스의 빈을 생성한 시 <property>태그를 이용해 타깃과 어드바이스 빈을 엮어준다. 그리고 사용할 어드바이스가 여러개이면 <value>태그로 추가한다.
Calulator.java
public class Calculator {
public void add(int x, int y) {
int result=x+y;
System.out.println("결과:"+ result);
}
public void subtract(int x, int y) {
int result=x - y;
System.out.println("결과:"+ result);
}
public void multiply(int x, int y) {
int result=x * y;
System.out.println("결과:"+ result);
}
public void divide(int x, int y) {
int result=x / y;
System.out.println("결과:"+ result);
}
}
LoggingAdvice.java
public class LoggingAdvice implements MethodInterceptor {
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("[메서드 호출 전 : LogginAdvice");
System.out.println(invocation.getMethod() + "메서드 호출 전");
Object object = invocation.proceed();
System.out.println("[메서드 호출 후 : LogginAdvice");
System.out.println(invocation.getMethod() + "메서드 호출 후");
return object;
}
}
인터페이스 MethodInterceptor를 구현하고 inveocation.proceed()메서드를 기준으로 메서드 호출 전과 후를 분리하여 로그 메시지를 출력한다.
proceed()메서드 호출 전 구문은 타깃 메서드 호출 전에 실행하는 기능이고, 호출 후 구문은 타깃 메서드 호출 후 실행하는 기능이다.
CalcTest.java
public class CalcTest {
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("AOPTest.xml");
Calculator cal=(Calculator)context.getBean("proxyCal");
cal.add(100,20);
System.out.println();
cal.subtract(100,20);
System.out.println();
cal.multiply(100,20);
System.out.println();
cal.divide(100,20);
}
}
AOPTest.xml를 읽어 들여 빈을 생성한 후 타깃 클래스의 메서드를 호출하면 결과 출력 전 후에 어드바이스에서 설정한 로그가 출력된다
참고 : ⌜자바 웹을 다루는 기술⌟ 책을 공부하며 요약・정리한 내용입니다.
'💻 Web_Back end > Spring' 카테고리의 다른 글
스프링 트랜잭션 기능 (0) | 2023.05.22 |
---|---|
스프링 JDBC 기능 (0) | 2023.05.16 |
스프링 MVC 기능 (0) | 2023.05.07 |
스프링 의존성 주입과 제어 역전 기능 (DI와 IoC) (0) | 2023.05.07 |
스프링 프레임워크 시작하기 (0) | 2023.05.06 |