[Spring] WIL - 4

진규빈·2024년 10월 11일

스프링 WIL

목록 보기
4/8

1. 스터디 복습

관점 지향 프로그래밍 (AOP)

횡단 관심사를 핵심 비즈니스 로직에서 분리하여 모듈성 향상시키는 프로그래밍 패러다임
• 핵심 기능과 부가 기능 분리 => 부가 기능과 적용할 위치 합쳐 Aspect라는 객체로 모듈화
◦ 애플리케이션 = 부가 기능 + 핵심 기능
◦ 부가 기능: 횡단 관심사 (Cross-cutting concerns) / 핵심 기능: 핵심 비즈니스 로직
• 빈 생성 및 소멸하는 방법 결정하여, 이를 통해 메모리 관리와 빈의 생성 시점 등을 세밀하게 컨트롤 가능

<AOP 용어>

Aspect
• 부가 기능을 모듈화한 것
• Advice + Pointcut
Target
• Aspect가 적용될 객체
• ex) 클래스, 메소드
Advice
• Aspect가 특정 JoinPoint에서 해야 하는 부가 기능 (What&When)
• types: before, after, after-returning, after-throwing, around
JoinPoint
• Advice가 적용될 수 있는 지점
• ex) 메서드 진입 시점, 생성자 호출 시점 등... / Spring AOP에서는 항상 메서드 진입 시점
Pointcut
• 어떤 JoinPoint에 Advice 적용할지 결정하는 기준
• ex) 클래스 이름, 메서드 이름, 파라미터 등... / Advice가 적용되지 않는 JoinPoint도 있음
Weaving
• Pointcut에 의해 결정된 Target의 JoinPoint에 Advice(부가 기능) 삽입하는 과정
• types: 컴파일 타임, 클래스 로드 타임, 런타임 위빙 / Spring AOP에서는 런타임 위빙만 사용

<스프링 AOP>

@AspectJ 방식 or XML 방식으로 구현 가능

// 1. @AspectJ 활성화
@Configuration
@EnableAspectJAutoProxy
public class AppConfig {
	// Spring 설정 클래스
}
// 2. Aspect 선언
@Aspect
@Component
public class LoggingAspect {
	// 3. Pointcut 선언
	@Pointcut("execution(* com.example.service.*.*(..))")
 	public void serviceLayerExecution() {
 		// Pointcut 정의
	}
 	// 4. Advice 선언
	@Before("serviceLayerExecution()")
 	public void logBeforeServiceMethod() {
 		System.out.println("서비스 메서드가 호출되기 전 로깅 실행");
 	}
}

프록시

• 스프링 AOP는 프록시를 기반으로 설계됨
• AOP 자체는 프록시 쓰지 않고도 다양하게 구현 가능하지만, 스프링은 기존의 코드 수정하지 않고 추가적인 동작 더하기 위해 프록시 사용
• 프록시 객체: 원래 객체를 감싸고 있는 객체
◦ 기존 객체의 인터페이스 유지하고 추가적인 동작 수행
◦ 접근 제어하고 싶거나 부가 기능 추가하고 싶을 때 사용
• 클라이언트가 객체 사용할 때 스프링 컨테이너는 대상 객체 대신, 대상 객체를 감싼 프록시 객체를 제공
◦ 핵심 비즈니스 로직 감싼 프록시가 부가 기능 수행 => 기존 코드 수정 없이도 부가 기능 추가 가능 => 중복 없이 핵심 로직과 부가 기능 분리 가능
• 프록시는 Target 객체에 대한 호출 가로채(Intercept) Advice의 부가 기능 수행한 후 Target의 핵심 기능 호출 (before Advice의 경우)

Aspect 우선순위

• 동일한 JoinPoint에 여러개의 Advice가 적용될 경우 원하는 순서대로 수행되지 않을 수 있으므로 Aspect들의 순서 지정해줘야 함

@Order 어노테이션

@Aspect
@Order(1)
@Component
public class MyAspect1 {
	// Executes first 
}
@Aspect
@Order(2)
@Component
public class MyAspect2 {
	// Executes later 
}

Ordered 인터페이스

import org.springframework.core.Ordered;
@Aspect
@Component
public class MyAspect1 implements Ordered {
	@Override
	public int getOrder() {
		return 1;
	}
	// Executes first 
}
@Aspect
@Component
public class MyAspect2 implements Ordered {
	@Override
	public int getOrder() {
		return 2;
	}
	// Executes later 
}

• 우선순위가 높을수록(숫자가 작을수록) 바깥의 프록시 객체

커스텀 어노테이션

  1. @interface 타입으로 정의
  2. 메타 어노테이션 추가
    ◦ 메타 어노테이션: 다른 어노테이션에 적용되기 위한 어노테이션

@Target 어노테이션 적용 대상
@Retention 어노테이션 보존 범위
@Documented Javadoc 포함 여부
@Inherited 자식에게 어노테이션 상속 여부

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
	String value() default "";
}

커스텀 어노테이션 기반 AOP

  1. AOP dependency 추가
  2. 커스텀 어노테이션 작성
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime {
}
  1. aspect 생성
  2. Pointcut, Advice 생성
@Aspect
@Component
public class ExampleAspect {
	@Around("@annotation(LogExecutionTime)")
	public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
		long start = System.currentTimeMillis();
		Object proceed = joinPoint.proceed();
		long executionTime = System.currentTimeMillis() - start;
		System.out.println(joinPoint.getSignature() + " executed in " + executionTime + "ms");
		return proceed;
	}
}
  1. 실행
@LogExecutionTime
public void serve() throws InterruptedException {
	Thread.sleep(2000);
}

2. 과제


src/main/java/week4/MonitorPerformance.java
성능 모니터링 위한 커스텀 어노테이션 @MonitorPerformance 정의

src/main/java/week4/PerformanceAspect.java
AOP 사용하여 성능 모니터링 구현

src/main/java/week4/service/AlgorithmController.java
컨트롤러

src/main/java/week4/service/AlgorithmService.java
실제 알고리즘 실행

src/main/java/week4/Week4Application

실행 결과 캡쳐

3. 김영한 스프링 입문 강의

11강. 회원서비스개발

12강. 회원서비스테스트



• 테스트 생성 단축기 ctrl + shift + t

13강. 컴포넌트스캔


• 자동 의존관계 설정 (DI)
• 골뱅이 붙이기 => 컴포넌트스캔

14강. 자바코드로직접

0개의 댓글