728x90
<!-- https://mvnrepository.com/artifact/aspectj/aspectjweaver -->
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
복사된 코드
pom.xml에가서
varsioin에
주위할점은 의존성 주입코드를 1.5.4로 가져왔으니까
org.aspectj-version를 1.5.4로 맞춰주어야 한다 안그러면 오류남
varsion에 org.aspectj-version을 넣어준다
그리고
root-context로 가서
<!-- 스프링 AOP 활성화 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!-- kr.or.ddit.aop 패키지를 컴포넌트 스캔 대상으로 등록 -->
<context:component-scan base-package="kr.or.ddit.aop"></context:component-scan>
위 코드를 추가해준다
aop패키지 밑 하위 클래스를 만들고
클래스 안에 코드 작성
ServiceLoggerAdvice클래스
package kr.or.ddit.aop;
import java.util.Arrays;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
import lombok.extern.slf4j.Slf4j;
/*
Aspect(애스팩트) : AOP의 단위가 되는 횡단 관심사
-횡단 관심사(Cross-Cutting Concern) : 핵심(core) 비즈니싀 로직(삼겹살구워먹기, 빵또아의 아이스크림)과
다소 거리가 있지만, 여러 모듈에서 공통적이고 반복적인 처리를 요구하는 내용
(불판닦기, 불판교체)
-횡단 관심사 분리(Separation of Cross-Cutting Concern) : 횡단 관심사에 해당하는
부분(불판닦기, 불판교체, 빵또아의 빵)을 분리해서 한곳으로 모음
-Component : 골뱅이Aspect와 짝궁. component-scan시 "여기 봐주세요" 의 의미
-JoinPoint : 어드바이스(툭정 조인 포인트(불판이 탔을때)에서 실행되는 코드, 횡단 관심사를 실제로 구현)가
적용될 수 있는 위치
- Advice : 어떤 부가기능(불판닦기)을 언제(삼겹살을 굽기 전(Before)에) 사용할지 정의
* 언제?
-Brfore : 조인포인트 전에 실행(삼겹살을 굽기 직전)
-After : 조인 포인트에서 처리가 완료된 후 실행(삼겹살을 굽고 먹은 직후 실행)
-Around : 조인 포인트 전후에 실행(삼겹살을 굽기 직전과 먹은 직후 실행)
-After Returning : 조인 포인트가 정상적으로 종료 후 실행
-After Throwing : 조인 포인터에서 예외 발생 시 실행. 예외가 발생안되면 실행 안 됨.
*/
@Slf4j
@Component
@Aspect
public class ServiceLoggerAdvice {
//로보트에 : AOP대상(로그, 보안, 트랜잭션, 에러)
//포인트컷 표현식. 별쩜쩜별괄호쩜쩜괄호
//execution : 포인트컷(대상(메소드)을 선별하는 것) 지정자
//* : 임의의 1개의 리턴타입
//..: 임의의 0개 이상
//kr.or.ddit.*..*(..)
// 패키지 밑의 각각의 패키지가 있고
// 그 하위의 모든 파일/패키지
// 각각의 메소드가 있고
// (..) : 모든 파라미터
@Before("execution(* kr.or.ddit.*..*(..))*")
public void starLog(JoinPoint jp) {
log.info("startLog");
// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여짐,
// 파라미터 타입은 무엇인지 보여줌
// kr.or.ddit.service.BoardService.register(BoardVO)
log.info("startLog : " + jp.getSignature());
log.info("startLog : " + jp.getSignature());
// .getArgs() : 전달 된 파라미터 정보를 보여줌
// [BoardVO [boardNo=127, title=개똥이]]
log.info("startLog : " + Arrays.toString(jp.getArgs()));
}
//AfterReturning 어드바이스
//조인 포인트가 정상적으로 종효한 후에 실행됨. 예외 발생시 실행 안 됨
@AfterReturning("execution(* kr.or.ddit.*..*(..))")
public void logReturning(JoinPoint jp) {
log.info("logReturning");
// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여짐,
// 파라미터 타입은 무엇인지 보여줌
log.info("logReturning : " + jp.getSignature());
}
//After Throwing 어드바이스
//조인 포인트에서 예외 발생 시 실행. 예외가 발생 안 되면 실행 안 됨
@AfterThrowing(pointcut="execution(* kr.or.ddit.*..*(..))", throwing = "e")
public void logException(JoinPoint jp, Exception e) {
log.info("logException");
// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여짐,
// 파라미터 타입은 무엇인지 보여줌
log.info("logException : " + jp.getSignature());
//예외 메시지를 보여줌
log.info("logException : " + e);
}
//After 어드바이스
// 조인 포인트 kr.or.ddit.service.BoardService.register(BoardVO) 완료 후
// 예외 발생이 되더라도 항상 실행 됨
@After("execution(* kr.or.ddit.*..*(..))")
public void endLog(JoinPoint jp) {
log.info("endLog");
// .getSignature() : 어떤 클래스의 어떤 메서드가 실행되었는지 보여짐,
// 파라미터 타입은 무엇인지 보여줌
log.info("endLog" + jp.getSignature());
// .getArgs() : 전달 된 파라미터 정보를 보여줌
// [BoardVO [boardNo=127, title=개똥이]]
log.info("endLog" + Arrays.deepToString(jp.getArgs()));
}
//ProceedingJoimPoint : around 어드바이스에서 사용
//횡단관심사 - 부수적, 포인트컷 대상
//스프링 크레임워크가 컨트롤 하고 있는 비즈니스 로직 호출을 가로챔. 책임이 around 어드바이스로 전가됨
// 그래서 비즈니스 메소드에 대한 정보를 around 어드바이스 메소드가 가지고 있고
// 그 정보를 스프링 컨테이너가 around 어드바이스 메소드로 넘겨주면
// ProceedingJoinPoint 객체로 받아서 around 어드바이스가 컨트롤 시 활용함
@Around("execution(* kr.or.ddit.*..*(..))")
public Object timeLog(ProceedingJoinPoint pjp) throws Throwable{
//메소드 실행 직전 시간 체킹
long startTime = System.currentTimeMillis();
log.info("pjpStart : " + Arrays.toString(pjp.getArgs()));
//메소드 실행
Object result = pjp.proceed();
//메소드 실행 직후 시가나 체킹
long endTime = System.currentTimeMillis();
log.info("pjpEnd : " + Arrays.toString(pjp.getArgs()));
//직후 시간- 직전 시간 => 메소드 실행 시간
log.info(pjp.getSignature().getName() + " : " +
(endTime - startTime));
return result;
}
}
'Spring > Spring 기초' 카테고리의 다른 글
web.xml를 통해서 HTTP오류처리(상태코드를 사용해서 처리) (0) | 2023.08.11 |
---|---|
Spring 트랜젝션 제어 처리 (0) | 2023.08.11 |
hibernate 라이브러리 (0) | 2023.08.09 |
Spring Ajax Post방식 사용 방법 (0) | 2023.08.04 |
파일 업로드 서비스impl코드 (0) | 2023.08.02 |