20.1 관점 지향 프로그래밍의 등장
- 모든 웹 애플리케이션에서 공통으로 사용하는 보조기능(ex. 로깅, 트랜잭션, 예외 처리, 이메일 통보 기능 등)은 일일이 구현하는 번거로움을 관점 지향 프로그래밍(AOP, Aspect Oriented Programming)으로 해결한다.
- AOP : 메서드 안의 주기능과 보조 기능을 분리한 후 선택적으로 메서드에 적용해서 사용하는 것
- AOP를 사용하면 전체 코드에 흩어져 있는 보조 기능을 하나의 장소에 모아서 관리할 수 있음
- 보조 기능을 자신이 원하는 주기능에 선택적으로 적용할 수 있음
20.2 스프링에서 AOP 기능 사용하기
- 여러가지 AOP 관련 용어
용어 | 설명 |
aspect | 구현하고자 하는 보조 기능 |
advice | aspect의 실제 구현체(클래스). 메서드 호출을 기준으로 여러 지점에서 실행됨. |
joinpoint | advice를 적용하는 지점. 스프링은 method 결합점만 제공. |
pointcut | advice가 적용되는 대상. 패키지이름/클래스이름/메서드이름을 정규식으로 지정하여 사용. |
target | advice가 적용되는 클래스를 의미. |
weaving | advice를 주기능에 적용하는 것. |
- 스프링 프레임워크에서 AOP 기능을 구현하는 방법
- 방법1) 스프링 프레임워크에서 제공하는 AOP 관련 API를 이용
- 방법2) @Aspect 애너테이션을 이용
< 방법1. 스프링 API를 이용한 방법 >
- 과정~
- Target 클래스를 지정
- Advice 클래스를 지정
- 설정파일에서 Pointcut을 설정
- 설정파일에서 Advice와 PointCut을 결합하는 Adviser를 설정
- 설정파일에서 스프링의 ProxyFactoryBean 클래스를 이용해 Target에 Advice를 설정
- getBean() 메서드로 빈 객체에 접근해 사용
- 스프링 API에서 제공하는 여러가지 Advice 인터페이스
추상 메서드 | 설명 | 인터페이스 |
void before(Method method, Object[] args, Object target) | 해당 메서드가 실행되기 전 실행 | MethodBeforeAdvice |
void afterReturning(Object returnValue, Method method, Object[] args, Object target) | 해당 메서드가 실행된 후 실행 | AfterReturningAdvice |
void afterThrowing(Method method, Object[] args, Object target, Exception ex) | 해당 메서드에서 예외 발생 시 실행 | ThrowsAdvice |
Object invoke(MethodInvocation invocation) | - 해당 메서드의 실행 전/후와 예외 발생 시 실행 - 위 세가지 인터페이스들의 기능을 동시에 수행 가능 |
MethodInterceptor |
>> afterThrowning을 제외하고 모두 예외처리로 throws Throwable를 함
>> 클래스를 생성한 뒤 위의 인터페이스를 구현하면(해당 추상 메서드를 구현하면) 됨
>> 인자 설명
- Method method : 대상 객체에서 실행된 메서드를 나타내는 메서드 객체
- Object[] args : 메서드 인자 목록
- Object target : 대상 객체
- Object returnValue : 대상 객체의 메서드가 반환하는 값
- Exception ex : 발생한 예외 타입
- MethodInvocation invocation : 대상 객체의 모든 정보를 담고 있는 객체(위의 method, args 등)
- >> invocation.proceed()로 타깃 메서드 호출을 명시
- 실습!!
- 프로젝트 생성 후 lib 클래스 패스 설정
- AOP 설정 파일 xml을 src 패키지에 생성
- xml) <bean> 태그를 이용해 타깃 빈과 어드바이스 빈 생성
- xml) 스프링의 ProxyFactoryBean 클래스 빈 생성 후 <property> 태그를 이용해 타깃 빈과 어드바이스 빈을 엮어줌
- 사용할 어드바이스가 여러개일 시 <value> 태그로 추가
<?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>
>> 3~4의 과정.. 타깃 클래스의 모든 메서드에 AOP기능이 적용된다.
5. 타겟 클래스 작성
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);
}
6. 어드바이스 클래스 작성
public class LoggingAdvice implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println("[메서드 호출 전 : LoggingAdvice");
System.out.println(invocation.getMethod()+" 메서드 호출 전"); //메서드 호출 전 수행
invocation.proceed(); //타깃 메서드 호출!!!
System.out.println("[메서드 호출 후 : LoggingAdvice");
System.out.println(invocation.getMethod()+" 메서드 호출 후"); //메서드 호출 후 수행
return null;
}
}
- CalcTest.java
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();
}
~ 결과~
'BackEnd > Spring' 카테고리의 다른 글
22장. 스프링 JDBC 기능 (0) | 2022.03.02 |
---|---|
21장. 스프링 MVC 기능 (0) | 2022.03.01 |
19장. 스프링 의존성 주입과 제어 역전 기능 (0) | 2022.02.27 |
18장. 스프링 프레임워크 시작하기 (0) | 2022.02.26 |
17장. 모델2 방식으로 효율적으로 개발하기 - ③ 답변형 게시판(답글쓰기, 페이징 구현) (2) | 2022.02.25 |
Comment