코딩 개발/Spring

Spring Logging 2탄 - @After

호소세 2023. 7. 9. 19:47
728x90
반응형

저번 시간에 알아본 @Before 어노테이션에 이어서 이번에는 @After 어노테이션을 이용해서 Logging을 해보겠습니다.


https://pabeba.tistory.com/192

 

AOP (Aspect Oriented Programming) 관점 지향 프로그래밍

AOP란? Aspect => 관점 Core Concern 핵심관심사 + Cross Cutting Concern 횡단관심사 or 공통관심사 시스템을 핵심관심사항과 공통관심사항으로 구분해 분석, 설계, 구현, 운영합니다. 공통, 반복 작업을 피하

pabeba.tistory.com

 

공통 관심사인 Logging에 대해 알아볼 텐데요. 바로 예제로 들어가서 알아볼까요?

 

@After 어노테이션 예제

사실 저번 예제와 다를게 별로 없는 예제이긴 하지만 결괏값을 보면서 알아봐요.

 

@Aspect
@Component
public class KeywordLoggingAspect {
	private Logger logger=LoggerFactory.getLogger(getClass());
	@After("execution(public * org.kosta.myproject.model.*Service.find*(..))")
	public void logging(JoinPoint point) {
		String className=point.getTarget().getClass().getName();
		String methodName=point.getSignature().getName();
		//core에 매개변수로 전달된 검색 키워드 정보 받음
		Object params[]=point.getArgs();
		String keyword="";
		for(int i=0;i<params.length;i++) {
			keyword+=params[i]+" ";
		}		
		logger.debug("AOP Cross Cutting Concern 로깅처리 core method {} keyword {}",methodName,keyword);
	}
}

 

1. @After 어노테이션도 위의 그림과 같은 원리로 작성하면 됩니다.

2. JoinPoint 객체를 이용해서 사용하고 있는 메서드의 정보를 가져옵니다.

3. JoinPoint 객체에 매개변수로 전달된 키워드 정보를 받아올 수 있는 getArgs() 메서드가 있습니다.

4. 이것들을 String으로 엮어서 keyword 변수에 저장합니다.

5. 신기한 것이 있는데, 메세지로 보낼 문장을 SQL PreparedStatement 같이 ?(물음표)로 저장하고 값을 넣어주면 그 값이 물음표에 들어가는 것처럼, logging에서도 {} 중괄호 안에 값을 넣어주면 그 값이 메시지에 찍혀 나오게 됩니다.

logger.debug("AOP Cross Cutting Concern 로깅처리 core method {} keyword {}",methodName,keyword);

이렇게 말이죠.

 

그리고 테스트를 해봐야겠죠?

 

<TestAOPEX.java>

public class TestAOPEx {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx=new AnnotationConfigApplicationContext(AppConfig.class);
		MemberService ms=(MemberService)ctx.getBean("memberServiceImpl");
		ProductService ps=(ProductService)ctx.getBean("productServiceImpl");
		// AOP 적용 전에는 실제 Core 객체가 스프링 컨테이너로부터 전달
		System.out.println(ms.getClass().getName());
		System.out.println(ps.getClass().getName());
		ms.findMemberById("java");
		ms.findMemberListByAddress("오리");
		ms.register("손흥민 토트넘");
		ps.findProductById("1");
		ps.findProductListByMaker("오뚜기");
		ps.findProductListByPriceAndMaker(1000, "롯데");
		ps.deleteProduct("2");
		ctx.close();
	}
}

결과 값은?

com.sun.proxy.$Proxy19

com.sun.proxy.$Proxy21

core findMemberById id:java

2023-07-09 19:35:05 DEBUG o.k.m.aop.KeywordLoggingAspect - AOP Cross Cutting Concern 로깅처리 core method findMemberById keyword java

core findMemberListByAddress:오리

2023-07-09 19:35:05 DEBUG o.k.m.aop.KeywordLoggingAspect - AOP Cross Cutting Concern 로깅처리 core method findMemberListByAddress keyword 오리

core register memberInfo:손흥민 토트넘

core findProductById id:1

2023-07-09 19:35:05 DEBUG o.k.m.aop.KeywordLoggingAspect - AOP Cross Cutting Concern 로깅처리 core method findProductById keyword 1

core findProductListByMaker maker:오뚜기

2023-07-09 19:35:05 DEBUG o.k.m.aop.KeywordLoggingAspect - AOP Cross Cutting Concern 로깅처리 core method findProductListByMaker keyword 오뚝이

core findProductListByPriceAndMaker price:1000 maker:롯데

2023-07-09 19:35:05 DEBUG o.k.m.aop.KeywordLoggingAspect - AOP Cross Cutting Concern 로깅처리 core method findProductListByPriceAndMaker keyword 1000 롯데

core deleteProduct id:2

결과를 보시면 core 메서드가 실행되고 나서 log가 출력되는 것을 확인할 수 있죠?

그리고 설정해 놓은 것처럼 find 메서드에서만 log가 출력되고요.

 

저번에 설명드린 것처럼 Proxy(프락치)이기 때문에 대신해서 Impl의 행동을 수행해 줍니다.

 

소감

문득 생각이 들었는데, 자신이 하고 있는 어떤 것들에 갑자기 불안한 마음이 생기면 여러분들은 어떻게 합니까? 특히 미래를 예측할 수 없는 것이라 더욱 불안하다면 무엇을 해야 하는 것이 좋을까요?

생각해 봤는데 너무 불안해하지 않아도 된다고 생각했습니다. 어떤 분야에 전문가가 되거나 미래에 반드시 성장할 산업에 있다면 아직은 미미하지만 10년 뒤 20년 뒤를 바라보면서 현재에 충실하면 된다고 생각합니다.

방향성을 잘 잡고 먼 미래를 보면서 꾸준히 자신의 맡은 바 임무를 수행하면 된다고 생각합니다. 처음부터 완벽한 것은 없습니다. 완벽하게 만드는 그 과정을 즐기면서 오늘 하루 편하게 보냈으면 좋겠습니다.

반응형