728x90
이전 시간에 SpringAOP이 뭔지 알아봤다.
그럼 이제 직접 설정해서 사용해보자 !
아직 SpringAOP이 이해가 안된다면 이전 게시글을 확인해주세요!
[ Spring ] SpringAOP 이론 ⑱
🤔SpringAOP 이란 ?💭 관점 지향 프로그래밍(Aspect Oriented Programming) 일반적으로 사용하는 클래스(Service, Dao 등) 에서 중복되는 공통 코드 부분(commit, rollback, log 처리) 을 별도의 영역으로 분리해 내
jnaa.tistory.com
🤔💭실행 순서
BeforeAspect ➡ AroundAspect ➡ AfterAspect
📚 Spring
📗 CommonPointcut.java
❗ @Pointcut를 설정한다
@Pointcut("execution(* edu.kh.project..*Impl*.*(..))")
edu.kh.project..*Impl* : 클래스 중 Impl이 들어간 클래스
*(..)) : 모든 메소드
package edu.kh.project.common.aop;
import org.aspectj.lang.annotation.Pointcut;
// Pointcut을 모아둘 클래스
public class CommonPointcut {
@Pointcut("execution(* edu.kh.project..*Impl*.*(..))")
public void serviceImplPointcut(){
}
}
📗 BeforeAspect.java
@Component
@Aspect // 공통 관심사가 작성된 클래스임을 지정
// Pointcut(타켓지정) + Advice(수행할 코드)
public class BeforeAspect {
private Logger logger = LoggerFactory.getLogger(BeforeAspect.class);
//execution([접근제한자(생략가능] 리턴타입(*) 클래스명(edu.kh.project..*Impl*) 메소드명 ([파라미터]))
//@Before("execution(* edu.kh.project..*Impl*.*(..))")//타겟 수행 전
// 지정된 클래스.메소드에 작성된 @Pointcut() 어노테이션의 내용을 타겟으로 삼음
@Order(1) // 순서, 하나의 타겟에 대한 여러 advice 수행 시 순서 지정
@Before("CommonPointcut.serviceImplPointcut()")
public void beforeLog(JoinPoint jp) { //Advice(수행할 코드)
// 매개변수 JoinPoint : AOP 부가 기능이 적용된 대상의 객체, 메소드, 파라미터 정보를 얻을 수 있게 해주는 객체
// 대상 객체의 간단한 클래스명(패키지명 제외)
String className = jp.getTarget().getClass().getSimpleName();
String str ="-------------------------------------------------------\n";
// 메소드 선언부(==메소드 시그니처)에서 메소드명만 얻어옴
String methodName = jp.getSignature().getName();
str += "[Start]:"+className + "-"+ methodName + "()\n";
//[Start] : MemberServiceImpl - login()
// jp.getArgs() : 파라미터묶음(배열)
str += "[Parameter] : " + Arrays.toString(jp.getArgs()) + "\n";
try {
// 접속자 IP 얻어오기
HttpServletRequest req = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes())
.getRequest();
Member loginMember = (Member) req.getSession().getAttribute("loginMember");
str += "[ip]" + getRemoteAddr(req);
if (loginMember != null) {
str += "(email:" + loginMember.getMemberEmail() + ")";
}
} catch (Exception e) {
str += "[스프링 스케쥴러]";
}
logger.info(str);
}
//ip 얻어오는 코드
public static String getRemoteAddr(HttpServletRequest request) {
String ip = null;
ip = request.getHeader("X-Forwarded-For");
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("WL-Proxy-Client-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_CLIENT_IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("HTTP_X_FORWARDED_FOR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-Real-IP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("X-RealIP");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getHeader("REMOTE_ADDR");
}
if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
ip = request.getRemoteAddr();
}
return ip;
}
}
📗 AroundAspect.java
@Component
@Aspect
public class AroundAspect {
// Logger : 로그를 작성할 수 있게하는 객체
private Logger logger = LoggerFactory.getLogger(AroundAspect.class);
// 전처리, 후처리를 모두 해결하고자 할 때 사용 하는 어드바이스
// proceed() 메소드 호출 전 : @Before advice 작성
// proceed() 메소드 호출 후 : @After advice 작성
// 메소드 마지막에 proceed()의 반환값을 리턴해야함.
@Order(2)
@Around("CommonPointcut.serviceImplPointcut()")
public Object aroundServiceLogs(ProceedingJoinPoint pp) throws Throwable {
// @Around advice는 JoinPoint Interface가 아닌
// 하위 타입인 ProceedingJoinPoint를 사용해야 함.
long startMs = System.currentTimeMillis(); // 서비스 시작 시의 ms 값
Object obj = pp.proceed(); // 여기가 기준
long endMs = System.currentTimeMillis(); // 서비스 종료 시의 ms 값
String str = "Running Time : " + (endMs- startMs) + "ms";
logger.info(str);
return obj;
}
}
📗 AfterAspect.java
@Component
@Aspect
public class AfterAspect {
private Logger logger = LoggerFactory.getLogger(AfterAspect.class);
@Order(3)
@After("CommonPointcut.serviceImplPointcut()")
public void afterLog() {
logger.info("------------------------------------------\n\n");
}
}
🔮 실행화면
728x90
'ON > spring' 카테고리의 다른 글
[ Spring ] 채팅 구현하기 - 실전편 ② (화면 구현 DB설정) (0) | 2023.09.04 |
---|---|
[ Spring ] 채팅 구현하기 - 이론편 ① (0) | 2023.09.04 |
[ Spring ] SpringAOP 이론 ⑱ (0) | 2023.09.01 |
[ Spring ] @Scheduled 이용하기 ⑰ (0) | 2023.09.01 |
[ Spring ] @Scheduled 이론 ⑯ (0) | 2023.09.01 |