Spring AOP after-returning day67

stan·2023년 8월 11일
0

Spring

목록 보기
13/22

advice마다 메서드명이 다를 수 있다

joinpoint는 around에서는 필수
다른 advice들은 필수가 아님

다형성을 사용하려면 누구나 사용하는 기법 : 바인딩 기법

e.g. 챔피언이라는 깡통안에 가렌, 티모를 넣음

이걸 가능하게 하는게 OOP의 다형성

Object returnObj : 바인딩변수
실제 output이 뭐였든 간에 (멤버였는 보드였든) 컨테이너가 Obj에 넣어줌

스프링컨테이너가 보드빈이든 멤버빈이든
Obj라는 깡통안에 넣어줌

applicationContext.xml

<bean id="afterReturningAdvice" class="com.spring.biz.common.AfterReturning"/>
<aop:config>
	<aop:aspect ref="afterReturningAdvice">
				<aop:after-returning method="afterReturningPrintLog" pointcut-ref="aPointcut" returning="returnObj"/>
	</aop:aspect>
</aop:config>

AfterReturning.java

package com.spring.biz.common;
import org.aspectj.lang.JoinPoint;

import com.spring.biz.member.MemberVO;
public class AfterReturning {			
	// pjp는 jp를 상속받은 객체
	// pjp는 aroundAdvie에서는 필수
	// 다른 advice들은 필수가 아님
	// 비즈니스 메서드의 정보를 받고싶을때 jp를 사용 
	// 나와 결합될 메서드의 output이 무엇인지 확실 하지 않음 == object사용
	public void afterReturningPrintLog(JoinPoint jp, Object returnObj) {//비즈니스의 output이 들어옴 
		String methodName=jp.getSignature().getName();
		// 비즈니스 메서드의 이름
		// 현재 해당 어드바이스와 결합된 비즈니스 메서드

		System.out.println("횡단관심 : "+methodName+"의 반환 이후의 로그");

		// returnObj가 관리자라면, 로그에 [관리자 입장]이라고 출력하고 싶음
		if(returnObj instanceof MemberVO) {//returnObj가 member라는 확신이 없음 : instanceof
			MemberVO mVO = (MemberVO)returnObj;
			if(mVO.getRole().equals("ADMIN")) {  
				System.out.println("[관리자입장]");
			}
			else System.out.println("[사용자입장]");
		}
		else System.out.println("[데이터열람]");//보드나 리스트였겠죠 
	}
}

===============================================================

AOP Annotation

AOP를 어노테이션으로 처리할게 라고 하는 설정

<aop:aspectj-autoproxy>

AroundAdvice.java


package com.spring.biz.common;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Service;
import org.springframework.util.StopWatch;

@Service
@Aspect
public class AroundAdvice {
	@Pointcut("execution(* com.spring.biz..*Imple.*(..))")
	public void aPointcut() {}
	@Pointcut("execution(* com.spring.biz..*Imple.select*(..))")
	public void bPointcut() {}
	
	@Around("bPointcut")
	public Object aroundPrintLog(ProceedingJoinPoint pjp) throws Throwable {
		System.out.println("around 로그 전");//메서드수행 전 출력
		
		///////시작!
		StopWatch sw = new StopWatch(); //stopwatch는 스프링에서 제공 해 줌 
		sw.start();
		
		Object obj=pjp.proceed(); //메서드들을 실행
		// 외부의 비즈니스 메서드를 호출함
		//obj에다 메서드 실행 결과 값 저장 
		
		///////끝!
		sw.stop();
		
		String methodName=pjp.getSignature().getName();
		System.out.println(methodName+"메서드를 수행하는데에 소요한 시간은"+sw.getTotalTimeMillis()+"초입니다.");
		
		System.out.println("around 로그 후");//메서드수행 후 출력
		
		return obj;//obj에 저장된 반환값을 반환
	}
}

Advice.java에 포인트컷에대한 정보를 알려줌
- body를 작성하지 않음

Advice를 new하는 코드 : @Component를 상속받은 @Service를 씀
:service를 쓴 ㄴ이유는 이 친구들이 결합되는 레이어가 Service라서
같은층에서 동일의 어노테이션을 쓰면 더 빨라짐
- 메모리관리가 더 유리함
@Component쓰면 아무 레이어에서 나 스캔

@Aspect걸어주기

profile
이진 입니다

0개의 댓글