kenzi
오늘의 질문 정리(advice는 어려워..&ComponentScan과 Component) 본문
1. xml 컨테이너에서
after-returning에서 returning = "ret"
ret가 뭔가? 어떤 객체를 return하라는 건가?
//컨테이너.xml
<aop:config>
<aop:aspect id = "loggingAspect" ref ="loggingAdvice">
<aop:pointcut id = "publicMethod" expression ="execution(public * ch05_obj.*Service.*(..))" />
<aop:after-returning method = "afterReturning"
pointcut-ref = "publicMethod" returning ="ret" />
<!-- afterReturing이라는 메서드 실행 언제? publicMethod가 실행되면 그 이후에 ! ret를 리턴하는 것 -->
</aop:aspect>
</aop:config>
loggingAdvice 클래스를 따라가서 afterReturning메서드를 보면
ret는 Object타입의 로컬변수인데
변수만 만들어놓았는데?
package ch05_obj;
//aspect로 실행될 메서드
public class LoggingAdvice {
public void before() {
System.out.println("[LA]메서드 실행 전 (before) 전처리 수행함.");
}
public void afterReturning(Object ret) {
System.out.println("[LA]메서드 정상 처리(afterReturning) 후 수행할 리턴값 : "+ ret);
}
public void afterThrowing(Throwable ex) {
System.out.println("[LA]메서드 예외발생 후 (afterThrowing) 수행함 예외: " + ex.getMessage());
}
public void afterFinally() {
System.out.println("[LA]메서드 실행 후 (afterFinally) 후처리 실행함");
}
} //end class
----------->
returning = "ret"는 핵심서비스 메서드의 리턴값이다
즉 aop가 걸린 메서드의 리턴값이다
pointcut-ref = "publicMethod" 에 의해
<aop:pointcut id = "publicMethod" expression ="execution(public * ch05_obj.*Service.*(..))" />
expression에 해당하는 *Service.*(..)의 모든 메서드에 aop가 걸린다
즉 main에서
//main
//main코드 생략 ..
AbstractApplicationContext ctx =
new GenericXmlApplicationContext("classpath:ch05_AOP/Container2.xml");
ReadArticleService service = ctx.getBean("readArticleService",ReadArticleService.class);
try {
service.getArticleAndReadCnt(1);
service.getArticleAndReadCnt(1);
service.getArticleAndReadCnt(0);
} catch (ArticleNotFoundException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
}
service.getArticleAndReadCnt(1); 이 실행되었을 때
리턴하는 값이 returning ="ret"에 해당된다
return new Article(id)가 ret에 해당된다
package ch05_obj;
public class ReadArticleServiceImpl implements ReadArticleService {
public Article getArticleAndReadCnt(int id) throws ArticleNotFoundException {
System.out.println("핵심서비스 ---getArticleAndReadCnt("+ id +") 호출됨--->조인포인트");
if(id ==0 ) {
throw new ArticleNotFoundException("id는 0이 안됨");
}
return new Article(id);
}
}// end class
그것을 Object ret 참조변수로 받아와서
Article의 toString으로 println되는 것
======> 이것은 더 나아가서 @After 와 @AfterReturning의 차이가 된다
@After는 핵심서비스 메서드가 실행되고 나서 정상적으로 실행되든지 실패하든지 결과에 상관없이 aspect메서드가 실행되고
@AfterReturning은 핵심서비스 메서드가 실행된 후 정상적으로 실행된 리턴값을 받아 aspect메서드에서 처리해야할때 사용하므로 returning태그는 꼭 있어야 하는 것이다
Spring AOP @After, @AfterReturning, @AfterThrowing 사용하기
시작하며 지난 번에 외부 API 연동을 하면서 인증을 하는 로직을 AOP로 분리했었다. 이번에는 해당 API를 호출하고 로그를 남기기 위해 AOP 사용한 내용을 공유해본다. 간단하게 상황을 설명하면 외
deepweller.tistory.com
2. 포인트 컷 쓸때
args(id,info)라고만 쓰면 어떤 메서드(핵심서비스 메서드)에 aop를 거는가?
----> 핵심서비스 메서드의 인자값(id,info) 타입으로 구분해서 건다
pointcut = "args(id111,info111)" returning = "ret" arg-names = "ret,id111,info111"이라고 바꿔도 결과가 똑같다
//컨테이너 위 코드 생략
<aop:aspect id = "traceAspect" ref = "traceAdvice">
<aop:after-returning method="traceReturn"
pointcut = "args(id,info)" returning = "ret" arg-names = "ret,id,info"/>
</aop:aspect>
그리고 핵심서비스 메서드 update는 인자값으로 memberId, info를 받는데?
id, info가 아니라? args(괄호안)은 어떤걸 보고 채워야하나?
----> 인자 값 이름은 중요하지 않다
..질문 3과 연결 ..
//aop 걸리는 핵심 서비스 메서드
public boolean update(String memberId, UpdateInfo info) {
System.out.println("MemberServiceImpl.update() 메서드 실행");
return false;
}
3. arg-names가 하는 역할이 뭔가?
arg-names는 aspect 메서드(traceReturn메서드)의 인자값이고
pointcut = args(id, info)에 의해 핵심서비스 메서드 인자값의 타입을 구분시켜주기 위해서 arg-names("")를 적어주어야 한다
traceReturn(aspect메서드)의 인자값 ret=> boolean 타입 , id => String 타입 , info => UpdateInfo 타입이다
pointcut = args(id,info)니까 aop가 걸리는 핵심서비스 메서드는 인자 값이 id => String 타입, info => UpdateInfo타입인 메서드에 걸린다 = update(String memberId, UpdateInfo info)
package ch05_obj;
public class UpdateMemberInfoTraceAdvice {
public void traceReturn(boolean result, String memberId, UpdateInfo info) {
System.out.println("[TA] 정보 수정 : 결과 = " + result + ", 대상회원 = "
+ memberId + ", 수정정보 = " + info);
}
}
4. @Component와 @ComponentScan 의 차이
@Component는 객체자신이 " 저 등록된 Bean입니다 " 표시해주는 것
@ComponentScan은 컨테이너에서 지금 여기 등록된 Bean말고 다른 곳에 있는 객체도 "제 Bean입니다" 표시하는 것
@ComponentScan(base-package="~")을 할거면 컨테이너에서 base-package에 있는 빈은 등록하면 안됨
'Spring' 카테고리의 다른 글
스프링 MVC (0) | 2022.04.06 |
---|---|
AOP의 order란? & expression표현은 다양하다 (0) | 2022.04.06 |
AOP (0) | 2022.04.05 |
오늘 수업에서 질문한 것(DI와 인터페이스 구현) (0) | 2022.04.04 |
pom.xml이 무엇인지 정리해보자 .. (0) | 2022.04.04 |