일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 계산기GUI
- 숫자정렬
- 자바
- 계산기
- annotation
- 자바 #java #이클립스 #eclipse #switch #switch문 #사칙연산 #계산기 #calculator #간단한계산기
- Swing
- 자바알고리즘
- 이클립스
- 스프링
- 자바 계산기
- 어노테이션
- 버블소트
- Spring
- 내림차순정렬
- GUI
- 배열정렬
- 이클립스 #이클립스단축키 #자바 #자바단축키
- 오름차순정렬
- 버블정렬
- 자바GUI
- MVC
- Java
- Eclipse
- 알고리즘
- Today
- Total
온 코딩
[Spring] AOP - 관심분리, 포인트컷, 어드바이스, 위빙, 애스팩트 + 표현식 모음 본문
AOP(Aspect Oriented Programming) 관점 지향 프로그래밍
- 관심분리
횡단관심 : 메소드마다 공통으로 등장하는 로깅이나 예외, 트랜잭션 처리 같은 코드 들
핵심관심 : 요청에 따라 실제로 수행되는 핵샘 비즈니스 로직
객체지향 프로그래밍에서는 횡단관심을 완벽하게 독립적으로 분리해내기가 어렵다
AOP 사용 전 준비사항
pom.xml 에 dependecy추가
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.8</version>
</dependency>
applictaionContext.xml 파일에서 Namespace aop 선택
applicationContext.xml에 bean 추가, 포인트컷 환경설정
<bean id="log" class="com.hhw.biz.common.LogAdvice"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.hhw.biz..*Impl.*(..))" id="allPointcut"/>
<aop:aspect ref="log">
<aop:before method="pringLog" pointcut-ref="allPointcut"/>
</aop:aspect>
</aop:config>
aop:pointcut expression 설명~~
<aop:pointcut expression="execution(* com.hhw.biz..*Impl.get*(..))" id="getPointcut"/>
execution(* com.hhw.biz..*Impl.get*(..))
(* 리턴타입 : 모든 타입
이후로는 메서드 로케이션
com.hhw.biz.. 패키지 구조
*Impl. ~~~Impl로 끝나는 파일
get*(..)) get으로 시작하는 모든 메서드
//참고 : *(..)) 모든 메서드
<aop:aspect ref="log">
<aop:before method="printLog" pointcut-ref="allPointcut"/>
</aop:aspect>
allPointcut에 정의된 메서드들이 실행되기 전에 log 빈의 printLog메서드를 실행함
printLog()메서드를 어드바이스라고 함! -공통으로 실행되는 코드
포인트 컷
1. 조인 포인트
: 클라이언트가 호출하는 모든 비즈니스 메서드
: 조인포인트 중에서 포인트컷이 선택되기 때문에 포인트컷 대상 또는 포인트컷 후보라고 한다.
2. 포인트 컷
: 필터링 된 조인포인트
: 수많은 비즈니스 메서드 중에서 우리가 원하는 특정 메서드에서만 횡단 관심에 해당하는 공통기능을 수행시키기 위해서 포인트 컷이 필요
: 메서드가 포함된 클래스와 패키지, 메서드 시그니처까지 정확하게 지정할 수 있다.
*위의 예제에서는 getPointCut이 get과 관련된 메서드를 잘라낸 포인트컷!
3. 어드바이스
: 횡단 관심에 해당하는 공통 기능의 코드 - 언제 동작할지 스프링 설정파일을 통해 지정 가능
: before, after, after-returning, after-throwing, around 다섯가지 위치가 있음
4. 위빙
: 핵심 관심 메서드가 호출 될 때, 어드바이스에 해당하는 횡단 관심 메서드가 삽입되는 과정
: 위빙 과정을 통해 관심분리가 가능한 것!
: 컴파일, 로딩, 런타임 위빙 중 스프링에서는 런타임위빙을 지원! (구동할 때 위빙한다~~)
5.애스팩트(어드바이저)
: 포인트컷+어드바이스
<aop:aspect ref="어드바이스클래스">
<aop:언제 method="어드바이스이름" pointcut-ref="어떤 포인트컷" />
</aop:aspect>
- 어떤 포인트컷에서 어떤 어드바이스 가져올건지!
*<aop:adviser> : 클래스를 임포트한 경우, 어드바이저를 사용! 메서드를 따로 지정하지 않아도 된다
+어드바이스 JoinPoint
- before
package com.hhw.biz.common;
import org.aspectj.lang.JoinPoint;
public class BeforeAdvice {
public BeforeAdvice() {
}
public void beforeLog(JoinPoint jp){
String method = jp.getSignature().getName(); //메서드 이름
Object[] args = jp.getArgs(); //전달받는 매개변수
System.out.println("[사전처리] 비즈니스 로직 수행 전 동작 : "+method+" / args정보 : "+args[0].toString());
}
}
- after
package com.hhw.biz.common;
public class AfterAdvice {
public AfterAdvice() {
// TODO Auto-generated constructor stub
}
public void finallyLog(){ //JoinPoint를 매개변수로 받지 않아도 실행 가능
System.out.println("[사후처리] 비즈니스 로직 수행 후 무조건 동작");
}
}
- after-returning
package com.hhw.biz.common;
import org.aspectj.lang.JoinPoint;
import com.hhw.biz.board.BoardVO;
public class AfterReturningAdvice {
public AfterReturningAdvice() {
// TODO Auto-generated constructor stub
}
public void afterLog(JoinPoint jp, Object returnObj){
String method = jp.getSignature().getName(); //메서드이름
if(returnObj instanceof BoardVO){ //returnOjb가 BoardVO의 객체라면!
BoardVO board = (BoardVO) returnObj; // 매개변수 returnObj(Context파일에 정의된 이름 사용)를 board값에 넣기
if(board.getContent().equals("contents")){
System.out.println(board.getTitle()+"내용은 contents");
}
}
System.out.println("[사후로직] 비즈니스 로직 수행 후 동작 : "+method+"메서드 리턴값"+returnObj.toString());
}
}
applicationContext.xml의
<aop:aspect>에서
<aop:after-returning>태그 안에 returning="returningObj"라는 속성 추가! 속성 값은 매개변수 값과 같아야한다.
- after-throwing
package com.hhw.biz.common;
import org.aspectj.lang.JoinPoint;
public class AfterThrowingAdvice {
public AfterThrowingAdvice() {
// TODO Auto-generated constructor stub
}
public void exceptionLog(JoinPoint jp, Exception exceptionObj){
// exceptionObj는 모든 오류를 받기 위해 Exception 사용, Context.xml파일에서 정의된 매개변수명 사용
// exceptionObj에는 오류값, 내용이 저장되어 있음
String method = jp.getSignature().getName();
System.out.println("[예외처리] 비즈니스 로직 수행 중 예외발생 : "+method+" / 예외메세지 : "+exceptionObj);
}
}
applicationContext.xml의
<aop:aspect>에서
<aop:after-throwing>태그 안에 throwing="exceptionObj"라는 속성 추가! 속성 값은 매개변수 값과 같아야한다.
- around
: 다른 어드바이스처럼 메인 로직 수행 전/후에 실행 되는 것이 아니라 메인의 로직을 ProceedingJoinPoint pjp 객체로 가로챈 후, 클래스 내에서 proceed() 메서드를 통해 로직 수행을 한다.
package com.hhw.biz.common;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;
public class AroundAdvice {
public AroundAdvice() {
// TODO Auto-generated constructor stub
}
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable{
//ProceedingJoinPoint을 매개변수로 받음!! - JoinPoint를 상속받고, proceed()메서드를 가지고 있음
String method = pjp.getSignature().getName();
StopWatch stopWatch = new StopWatch(); // 스탑워치 클래스
System.out.println("[BEFORE] : 비즈니스 메서드 수행 전 //메서드 시그니처 :"+method);
stopWatch.start();
Object returnObj = pjp.proceed(); // 가로 챈 로직을 수행함
stopWatch.stop();
System.out.println("[AFTER] : 비즈니스 메서드 수행 후 // 수행에 걸린 시간 : "+stopWatch.getTotalTimeMillis()+"(ms)초");
return returnObj;
}
}
표현식 모음
1. 리턴타입 지정
표현식 | 설명 |
* | 모든 리턴타입 허용 |
void | 리턴타입이 void인 메서드 |
!void | 리턴타입이 void가 아닌 메서드 |
2. 패키지 지정
표현식 | 설명 |
com.hhw.biz | com.hhw.biz 패키지만 선택 |
com.hhw.biz.. | com.hhw.biz 로 시작하는 모든 패키지 선택 |
com.hhw.biz..impl | com.hhw.biz로 시작하면서 마지막 패키지 이름이 impl로 끝나는 패키지 선택 |
3. 클래스 지정
표현식 | 설명 |
BoardServiceImpl | BoardServiceImpl 클래스만 선택 |
*Impl | 클래스 이름이 Impl로 끝나는 모든 클래스 선택 |
BoardService+ | 해당 클래스로부터 파생된 모든 자식클래스 선택(구현, 상속 등) |
4. 메서드 지정
표현식 | 설명 |
*(..) | 기본설정으로 모든 메서드를 선택 |
get*(..) | get으로 시작하는 모든 메서드 선택 |
5. 매개변수 지정
표현식 | 설명 |
(..) | 기본타입, 매개변수의 갯수와 타입에 제약 없음 |
(*) | 반드시 1개 이상의 매개변수를 가지는 메서듬나 선택 |
(com.hhw.user.UserVO) | 매개변수에 UserVO를 가지는 메서드만 선택(클래스 경로 반드시 적기) |
(!com.hhw.user.UserVO) | 매개변수에 UserVO를 가지지 않는 메서드만 선택 |
(Integer, ..) | 한 개 이상의 메서드를 가지되 첫번째 매개변수는 무조건 Integer |
(Integer, *) | 두 개 이상의 메서드를 가지되 첫번째 매개변수는 무조건 Integer |
'복습 ARCHIVE > 모델별 프로젝트' 카테고리의 다른 글
[Spring] 스프링 트렌젝션 처리 - JDBC기반 관리자 등록, <tx:advice> 설정, <aop:adivisor> 설정, (0) | 2021.06.21 |
---|---|
[Spring] 어노테이션을 활용한 AOP (0) | 2021.06.18 |
[Spring]오라클 DB연결 jdbcTemplate 메서드 모음 (0) | 2021.06.17 |
[Spring] 오라클 DB 연결 - JdbcDaoSupport 상속 / JdbcTemplate (0) | 2021.06.17 |
[Spring] 오라클 DB 연결 - JDBCUtil 사용 (0) | 2021.06.16 |