Notice
Recent Posts
Recent Comments
Link
개발 무지렁이
[Spring] 관점지향프로그래밍 AOP와 Advice, 프록시 서버(Proxy Server) 본문
AOP(Aspect Oriented Programming)
별도의 모듈(라이브러리 덩어리)로 만들어 놓고, 호출해서 사용
(관점을 핵심기능과 공통기능으로 분리)
(관심사항을 등록해놓으면, 타겟대상을 찾아서 사전 / 사후처리, Filter와 같은 역할)
WHY?
요구사항 변경에 소스코드 변경을 최소화
🧩범용성 코딩 Style, 🧩직관성
Advice 객체
🚀. AOP 적용시기
Around: 사전, 사후
Before: 사전
After: 사후 (예외여부 상관없이)
After-returning: 사후 (정상동작시)
After-throwing: 사후 (예외발생시)
⭐. AspectJ (어노테이션 이용)
@Around
@Before
@After
@After-returning
@After-throwing
📌. join point & pointCut
: Advice를 적용할 지점(method) - joinPoint
: 여러개의 join point를 하나의 pointCut으로 묶는다.
⚠️. pointCut: advice 적용시기 결정, proxy server에게 알려줌
⚠️. pointCut + advice = adviser
: Advice를 적용할 지점(method) - joinPoint
: 여러개의 join point를 하나의 pointCut으로 묶는다.
⚠️. pointCut: advice 적용시기 결정, proxy server에게 알려줌
⚠️. pointCut + advice = adviser
[TimerAdvice.java]
public class TimerAdvice {
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
// 사전처리, 타겟대상의 메서드 정보 가져오기
String methodName = joinPoint.getSignature().getName();
System.out.println("[ LOG ] " + methodName + "호출 전 사전처리중입니다...");
Object[] params = joinPoint.getArgs();
for(Object o : params) {
System.out.print(o + ", ");
}
System.out.println();
StopWatch sw = new StopWatch();
sw.start();
Object obj = joinPoint.proceed(); // 실제 핵심기능을 담당하는 메서드 호출
// 사후 처리
sw.stop();
System.out.println("[ LOG ] " + methodName + " 리턴값 obj: " + obj);
System.out.println("[ LOG ] " + methodName + " 의 총 실행 ms: " + sw.getTotalTimeMillis() + "ms");
System.out.println("[ LOG ] " + methodName + " 사후처리 완료되었습니다..\n");
return obj;
}
}
📌. ProceedingJoinPoint joinPoint
: 메서드에 대한 정보가 있다.
- getSignature(): 원형정보, method 모양
- getArgs(): 인자(parameter)정보, Object[] 반환
: 메서드에 대한 정보가 있다.
- getSignature(): 원형정보, method 모양
- getArgs(): 인자(parameter)정보, Object[] 반환
📌. (ProceedingJoinPoint) joinPoint.proceed();
// target method Invocation, 실제 핵심기능을 담당하는 method 호출, 사전과 사후의 기준
// target method Invocation, 실제 핵심기능을 담당하는 method 호출, 사전과 사후의 기준
AOP 프록시 서버에게 위빙(위임)한다
🚀. AOP 설정 [springAOP.xml]
⚠️. 적용방법(XML기반 / Java기반)
<aop:config>
<aop:aspect id="aspect" ref="advice">
<aop:around method="around" pointcut="execution(public * exam.service.*Impl.*ello(..))" />
</aop:aspect>
</aop:config>
<!-- AspectJ(어노테이션 이용)시 -->
<aop:aspectj-autoproxy />
⚠️ J2SE방식 (인터페이스 有) vs CGLIB방식 (인터페이스 x)
AOP proxy server 생성시 proxy-target-class="true"옵션은 CGLIB방식을 결정 (default: J2SE방식)
[MessageServiceImpl.java]
⚠️ MessageService 인터페이스 생략
public class MessageServiceImpl implements MessageService {
@Override
public void korHello() {
System.out.println("MessageServiceImpl의 korHello() 메서드 핵심로직입니다...");
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
@Override
public void engHello() {
System.out.println("MessageServiceImpl의 engHello(String name) 메서드 핵심로직입니다...");
try {
Thread.sleep(1000);
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}
[MainApp.java]
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("springAOP.xml");
MessageService service = context.getBean("target", MessageService.class);
service.engHello();
System.out.println("-----------------------------");
service.korHello();
System.out.println("-----------------------------");
}
}
'Backend > 스프링' 카테고리의 다른 글
[Spring] 어노테이션(annotation)과 파라미터(parameter), 리턴(return) (0) | 2023.05.05 |
---|---|
[Spring] front Controller: DispatcherServlet(in web.xml)과 Spring MVC bean(in SPRING BEAN 설정문서.xml) (0) | 2023.05.02 |
[Spring] 생성과 주입의 annotation, & 활성화 (0) | 2023.04.30 |
[Spring] 환경설정정보(.properties) 바인딩 (0) | 2023.04.30 |
[Spring] Spring Container에 의한 제어의 역행(Inversion Of Control)과 DI (0) | 2023.04.30 |
Comments