kenzi

오늘의 질문 정리(advice는 어려워..&ComponentScan과 Component) 본문

Spring

오늘의 질문 정리(advice는 어려워..&ComponentScan과 Component)

kenzi 2022. 4. 5. 17:01

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
Comments