빅토리 코딩
article thumbnail
Published 2023. 3. 28. 10:40
Srping AOP 설정(LogAspect) Spring
728x90
반응형

개요

mapping 되어있는 post, get으로 들어올 때 @RequestParam 또는 @RequestBody로 들어오는 데이터를 받아오는데 들어오는 것을 무조건 로그로 찍어내는 AOP를 만들러 보았다.


설명

- AOP

AOP는 Aspect-Oriented Programming의 약자로 여러 부분에서 공통적으로 발생하는 작업 (cross-cutting concerns)을 모듈화하여 코드의 중복을 줄이고 유지 보수성을 향상시키는 프로그래밍 기법이다. 예를 들어, 로깅, 보안, 트랜잭션 처리 등은 어플리케이션의 여러 부분에서 공통적으로 발생하는 작업으로, AOP를 이용하면 이러한 작업들을 모듈화하여 코드의 중복을 피할 수 있다.
 
핵심 개념

1. Aspect : 어플리케이션에서 공통적으로 발생하는 작업을 구현한 모듈

Aspect의 구현은 xml, java를 이용하여 configuration 할수 있다.
- xml
...
	<!-- advisor 설정한 Class bean 등록 -->
    <bean id='advisorTest' class='com.victory.advisor.AdvisorTest'/>
    
    <!-- AOP 설정 -->
	<aop:config>
    	<!-- advisor Class aspect conig 설정-->
		<aop:aspect ref='advisorTest'>
        	<!-- pointcut 시점 설정-->
			<aop:pointcut id="pointcutTest" expression="execution(* com.victory..*Controller.*(..))"/>
            <!-- pointcut에서 시행할 method 설정-->
            <aop:before method="beforeTest" pointcut-ref="pointcutTest"/>
		</aop:aspect>
	</aop:config>
...
 

- java


@EnableAspectJAutoProxy
@Aspect
@Component
public class AdvisorTest {

	@Before("execution(* com.victory..*Controller.*(..))")
	public Object beforeTest(JoinPoint joinpoint) throws Throwable {

		return joinpoint;
	}
}

2. Advice: Join Point에서 수행되는 작업

Advice의 설정 상태는Before(작업이전), After Returning(작업이후 리턴할때), After Throwing(작업중 예외를 던졌을때), After(작업이후), Around(작업 전후)가 있다.
 

3. Join Point : 어플리케이션 실행 중에 공통 작업이 삽입될 수 있는 지점

Join Point는 advice에서 설정한 상태에서 비즈니스 메소드 이름, 그 메소드가 속한 클래스와 패키지 정보, 가지고있는 메소드에 매개변수 등의 정보들이 들어있어advice 메소드 매개변수로 JoinPoint가 사용되는 것이다.
 

4. Pointcut: Join Point의 집합으로, Advice가 적용될 지점을 결정

Pointcut은 execution(Advice를 적용할 메서드), with(메서드가 아닌 특정타입(class)에 속한 메서드), bean(bean명인 모든 메서드)

5. Weaving: Aspect를 핵심 비즈니스 로직에 적용하는 과정


구현

spring aop를 이용하여 @Arround를 이용하여  project안에  *Controller안에 있는 method들이 시작될 때  해당 proceedingJoinPoint를 가져와 로그를 찍고 method가 실행되고 반환되는 값도 로그를 찍을 것이다.

@Arround는 중간에 메서드가 실행하는 부분이 있어서 proceedingJoinPoint를 매개변수로 쓰고
나머지는 JoinPoint를 매개변수로 사용한다.

pom.xml에 spring aop 의존성 추가

...		
        <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-aop</artifactId>
		</dependency>
...

java config

@Slf4j
@EnableAspectJAutoProxy
@Aspect
@Component
public class LogAspect {

	// @Arroud전후작업에 모두 사용 
    // 적용할 메서드를 명시	 리턴패턴   패키지안에  *Contorller에있는 모든 메소드      해당 메소드에 있는 매개변수 불러오기
    // execution			(*        com.victory..*Controller.*(..)          &&   args(params,..)
    
	@Around("execution(* com.victory..*Controller.*(..)) && args(params,..)") 
	public Object logBefore(ProceedingJoinPoint joinpoint, Map<String, Object> params) throws Throwable {
		ObjectMapper mapper = new ObjectMapper();

		//HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.currentRequestAttributes()).getRequest();

		log.info("==== ReqParam : " + params);
        
		//메소드 실행 (joinpoint.proceed()을 안하면설정한 메소드들은 실행을 안한다.)
		Object proceed = joinpoint.proceed();

		Map<String, Object> resMap = new HashMap<>();

		if (proceed instanceof Map) {
			//
			resMap.put("resultValue", mapper.writerWithDefaultPrettyPrinter().writeValueAsString(proceed));
		} else {
			resMap.put("resultValue", proceed);
		}

		log.info("==== ResParam : " + resMap.get("resultValue"));
		return proceed;
	}
}

Controller

...

	@PostMapping("/test")
	public Map<String, Object> test(@RequestBody @Parameter Map<String, Object> param) throws Exception {

		log.debug("param : ", param);
		Map<String, Object> result = new HashMap<>();

		result.put("resultKey","resultValue");

		return result;

	}
...

/test를 호출하면 로그에 잘 나오는 것을 확인할 수 있다.

 

https://github.com/victory940209/testspringboot/tree/main/simpleSpringboot

 

GitHub - victory940209/testspringboot

Contribute to victory940209/testspringboot development by creating an account on GitHub.

github.com

 

728x90
반응형

'Spring' 카테고리의 다른 글

Spring Validation (@Valid, @Validated)  (0) 2023.03.17
Swagger 3.x 와 spring doc [2]  (0) 2023.03.15
Swagger 3.x 와 spring doc [1]  (0) 2023.03.14
profile

빅토리 코딩

@빅토리 코딩

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그