티스토리 뷰
어드바이스는 각 조인포인트에 삽입되어 동작할 횡단 관심에 해당하는 공통 기능이며, 동작 시점은 설정 파일에서 설정이 가능하다.
스프링 프레임워크에서는 총 다섯가지의 동작 시점을 제공한다.
동작 시점 | 설명 |
Before | 비즈니스 메서드 실행 전 동작 |
After | - After Returning: 비즈니스 메서드가 성공적으로 리턴되면 동작 (try) - After Throwing: 비즈니스 메서드가 실행 중 예외가 발생하면 동작 (catch) - After: 비즈니스 메서드가 실행된 후, 무조건 실행 (finally) |
Around | 메서드 호출 자체를 가로채 비즈니스 메서드 실행 전, 후에 처리할 로직을 삽입할 수 있음 |
간단하게 예제들을 한번 확인해보자. 횡단 관심을 제외한 공통 예제 코드는 다음과 같다.
◎UserServiceImpl
package com.choonham.biz.board.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.choonham.biz.board.UserService;
import com.choonham.biz.board.UserVO;
@Service("userService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDAO userDAO;
@Override
public UserVO getUserInfo(UserVO vo) {
System.out.println("ㅎㅅㅎ");
return userDAO.getUserInfo(vo);
}
public UserServiceImpl() {
// TODO Auto-generated constructor stub
}
}
◎Main
package com.choonham.biz;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.choonham.biz.board.UserService;
import com.choonham.biz.board.UserVO;
public class Client {
public static void main(String[] args) {
AbstractApplicationContext container = new GenericXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)container.getBean("userService");
UserVO vo = new UserVO();
vo.setId("123");
vo.setPassword("1234");
UserVO user = userService.getUserInfo(vo);
if(user != null){
System.out.println(" 끝!!");
}
container.close();
}
}
1. Before
◎BeforeLog (횡단 관심)
package com.choonham.biz.board.common;
public class BeforeLog {
public void printLog() {
System.out.println("[Advice] I'm Before!");
}
public BeforeLog() {
// TODO Auto-generated constructor stub
}
}
◎xml 설정 파일
<bean id = "before_log" class = "com.choonham.biz.board.common.BeforeLog"></bean>
<bean id = "after_return_log" class = "com.choonham.biz.board.common.AfterReturnLog"></bean>
<bean id = "after_throw_log" class = "com.choonham.biz.board.common.AfterThrowingLog"></bean>
<bean id = "after_log" class = "com.choonham.biz.board.common.AfterLog"></bean>
<bean id = "around_log" class = "com.choonham.biz.board.common.Around"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.*(..))" id="allPointcut"/>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.get*(..))" id="getPointcut"/>
<aop:aspect ref="before_log">
<aop:before pointcut-ref="allPointcut" method = "printLog"/>
</aop:aspect>
</aop:config>
2. after-returning
◎AfterReturnLog (횡단 관심)
package com.choonham.biz.board.common;
public class AfterReturnLog {
public void printLog() {
System.out.println("[Advice] I'm AfterReturning!");
}
public AfterReturnLog() {
// TODO Auto-generated constructor stub
}
}
◎xml 설정 파일
<bean id = "before_log" class = "com.choonham.biz.board.common.BeforeLog"></bean>
<bean id = "after_return_log" class = "com.choonham.biz.board.common.AfterReturnLog"></bean>
<bean id = "after_throw_log" class = "com.choonham.biz.board.common.AfterThrowingLog"></bean>
<bean id = "after_log" class = "com.choonham.biz.board.common.AfterLog"></bean>
<bean id = "around_log" class = "com.choonham.biz.board.common.Around"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.*(..))" id="allPointcut"/>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.get*(..))" id="getPointcut"/>
<aop:aspect ref="after_return_log">
<aop:after-returning pointcut-ref="allPointcut" method = "printLog"/>
</aop:aspect>
</aop:config>
3. after-throwing
◎AfterThrowingLog (횡단 관심)
package com.choonham.biz.board.common;
public class AfterThrowingLog {
public void printLog() {
System.out.println("[Advice] I'm AfterThrowing!");
}
public AfterThrowingLog() {
// TODO Auto-generated constructor stub
}
}
◎xml 설정 파일
<bean id = "before_log" class = "com.choonham.biz.board.common.BeforeLog"></bean>
<bean id = "after_return_log" class = "com.choonham.biz.board.common.AfterReturnLog"></bean>
<bean id = "after_throw_log" class = "com.choonham.biz.board.common.AfterThrowingLog"></bean>
<bean id = "after_log" class = "com.choonham.biz.board.common.AfterLog"></bean>
<bean id = "around_log" class = "com.choonham.biz.board.common.Around"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.*(..))" id="allPointcut"/>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.get*(..))" id="getPointcut"/>
<aop:aspect ref="after_throw_log">
<aop:after-throwing pointcut-ref="allPointcut" method = "printLog"/>
</aop:aspect>
</aop:config>
또한 Exception 을 발생시켜야하기 때문에 비즈니스 로직을 조금 변경했다.
◎UserServiceImpl
package com.choonham.biz.board.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.choonham.biz.board.UserService;
import com.choonham.biz.board.UserVO;
@Service("userService")
public class UserServiceImpl implements UserService{
@Autowired
private UserDAO userDAO;
@Override
public UserVO getUserInfo(UserVO vo) {
vo = null;
System.out.println("ㅎㅅㅎ");
return userDAO.getUserInfo(vo);
}
public UserServiceImpl() {
// TODO Auto-generated constructor stub
}
}
4. after
◎AfterLog (횡단 관심)
package com.choonham.biz.board.common;
public class AfterLog {
public void printLog() {
System.out.println("[Advice] I'm After!");
}
public AfterLog() {
// TODO Auto-generated constructor stub
}
}
◎xml 설정 파일
<bean id = "before_log" class = "com.choonham.biz.board.common.BeforeLog"></bean>
<bean id = "after_return_log" class = "com.choonham.biz.board.common.AfterReturnLog"></bean>
<bean id = "after_throw_log" class = "com.choonham.biz.board.common.AfterThrowingLog"></bean>
<bean id = "after_log" class = "com.choonham.biz.board.common.AfterLog"></bean>
<bean id = "around_log" class = "com.choonham.biz.board.common.Around"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.*(..))" id="allPointcut"/>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.get*(..))" id="getPointcut"/>
<aop:aspect ref="after_throw_log">
<aop:after-throwing pointcut-ref="allPointcut" method = "printLog"/>
</aop:aspect>
<aop:aspect ref="after_log">
<aop:after pointcut-ref="allPointcut" method = "printLog"/>
</aop:aspect>
</aop:config>
5. around
around 어드바이스는 클라이언트의 메서드 호출을 가로채기 때문에 클라이언트가 호출한 비즈니스 메서드가 실행되기 전에 사전 로직 처리를 할 수 있으며, 비즈니스 메서드가 모두 실행되고 나서도 사후 로직 처리를 수행할 수 있다.
이를 위해 코드는 다음과 같이 구성한다.
◎AroundLog (횡단 관심)
package com.choonham.biz.board.common;
import org.aspectj.lang.ProceedingJoinPoint;
public class Around {
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("[before]: before");
Object returnObj = pjp.proceed();
System.out.println("[after]: after");
return returnObj;
}
public Around() {
// TODO Auto-generated constructor stub
}
}
pjp.proceed() 메서드 호출 앞에 작성된 코드는 Bofore 과 동일하게 동작하며, 메서드 호출 뒤에 작성된 코드는 After 와 동일하게 동작한다.
◎xml 설정 파일
<bean id = "before_log" class = "com.choonham.biz.board.common.BeforeLog"></bean>
<bean id = "after_return_log" class = "com.choonham.biz.board.common.AfterReturnLog"></bean>
<bean id = "after_throw_log" class = "com.choonham.biz.board.common.AfterThrowingLog"></bean>
<bean id = "after_log" class = "com.choonham.biz.board.common.AfterLog"></bean>
<bean id = "around_log" class = "com.choonham.biz.board.common.Around"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.*(..))" id="allPointcut"/>
<aop:pointcut expression="execution(* com.choonham.biz.board..*UserServiceImpl.get*(..))" id="getPointcut"/>
<aop:aspect ref="around_log">
<aop:around pointcut-ref="allPointcut" method = "aroundLog"/>
</aop:aspect>
</aop:config>
반응형
'[JAVA] > Spring' 카테고리의 다른 글
[Spring] AOP: 어노테이션을 이용한 구현 (0) | 2021.06.18 |
---|---|
[Spring] AOP: JoinPoint (0) | 2021.06.18 |
[Spring] AOP 용어 정리 (0) | 2021.06.17 |
[Spring] AOP(Aspect Oriented Programming) (0) | 2021.06.17 |
[Spring] Spring JDBC 2 : DAO Class 구현 (0) | 2021.06.17 |
Comments
최근에 올라온 글
최근에 달린 댓글
TAG
- 파니노구스토
- redux
- react
- await
- 이탈리안 레스토랑
- javascript
- 정보보안기사 #실기 #정리
- 인천 구월동 이탈리안 맛집
- react-native
- 맛집
- AsyncStorage
- Async
- 인천 구월동 맛집
- Promise
- redux-thunk
- Total
- Today
- Yesterday