AOP
AOP는 관점 지향 프로그래밍이라고도 불립니다.
어떤 로직을 기준으로 핵심적인 관점, 부가적인 관점으로 나눠보고
그 관점을 기준으로 각각 모듈화 하겠다는 의미로 다양한 기능을 분리해 보는 것입니다.
Spring 프레임워크에서는 AOP를 지원하며,
특히 애플리케이션의 트랜잭션 관리, 보안, 로깅 등의 단순화된 구현을 가능하게 합니다.
실습해 보기
테스트를 하기 위해
OwnerController와 Owner를 만들어 줍니다.
package org.example.controller;
import lombok.extern.slf4j.Slf4j;
import org.example.model.Owner;
import org.springframework.stereotype.Component;
@Component
@Slf4j
public class OwnerController {
public void getOwners() {
log.info("getOwners() called");
}
public void addOwner(Owner owner){
log.info("addOwner(owner) called");
}
}
package org.example.model;
public class Owner {
private int id;
private String name;
public Owner(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Owner{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
그리고 AOP를 사용하여 컨트롤러 클래스 내 메서드가 실행될 때 로깅을 수행하는 기능을 구현해 보겠습니다.
- @Aspect: 이 클래스가 AOP에서 사용될 '관점(Aspect)'임을 스프링에게 알리는 것입니다.
'Aspect'는 프로그램의 핵심 기능 외에 공통으로 적용할 관심사(로깅, 트랜잭션 관리 등)를 모듈화 하여 처리할 수 있게 합니다. - @Component: 스프링 컨테이너에 이 클래스를 빈(bean)으로 등록하기 위해 사용됩니다.
AOP는 스프링의 빈으로 등록된 클래스에서만 동작하기 때문에 @Component가 필요합니다.
package org.example.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.Joinpoint;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
* LoggingAspect
* - 로깅에 대한 부가 기능을 바라보는 하나의 관점
* 그 관점을 비즈니스 로직에서부터 별도의 파일인 LoggingAspect.java에 분리
*
* Aspect에서 사용되는 용어
* Advice - 횡단 관심사를 구현하는 Aspect의 메서드 - 여기서는 logBefore()
* JoinPoint - Advice를 적용할 메서드
* Pointcut - 각 Adivce에서 해당 Advice를 적용할 메서드를 구별시켜주는 구별자
*/
@Aspect // 스프링에게 해당 클래스가 AOP에서 사용될 하나의 Aspect라고 명시
@Component // 스프링 컨테이너에 해당 클래스를 bean으로 등록해서 AOP 프레임워크가
// 이 Aspect를 사용할 수 있게 적용
@Slf4j // 컨트롤러에서 분리될 로깅 코드가 필요하기 때문에 추가
public class LoggingAspect {
// value - 스프링 AOP가 logBefore()라는 Advice를 적용할 대상 메서드(Target)
// 에 대한 규칙 or 패턴(PointCut식)을 작성하는 부분
// execution: 메서드의 이름 패턴을 사용하겠다
// execution( * : 메서드의 반환 타입은 무엇을 사용하든 관계 없음
// org.example.controller : 해당 패키지의 하위에 속해야 함
// *Controller : 메서드의 이름이 Controller로 끝나야 함
// *( ) : 메서드의 인수 역시 무엇을 사용하든 관계 없음
// (..) : 대상 메서드가 인수를 받지 않을 수도 있고, 하나 이상의 임의의 개수의 인수를 받아도 상관없음
@Before(value = "execution(* org.example.controller.*Controller.*(..))")
public void logBefore(JoinPoint joinPoint) { // JoinPoint는 Advice를 적용할 대상 메서드
// AOP만의 부가 로직을 작성하는 부분
log.info("-- " + joinPoint.getTarget().getClass().getSimpleName() + "'s "
+ joinPoint.getSignature().getName());
}
}
그다음 애플리케이션에서 필요한 빈(bean)을 정의하거나 구성하는 클래스를 만들어주도록 하겠습니다.
- @EnableAspectJAutoProxy는 스프링 AOP(Aspect-Oriented Programming)를 활성화하는 설정입니다.
- 위에서 만든 LoggingAspect를 사용하기 위해 써줍니다.
- 주의할 점으로 @ComponentScan(basePackageClasses = App.class)으로 해주어야 합니다.
(뒤에 적어준 클래스가 속한 패키지를 기준으로 스캔하여 빈을 등록하기 때문입니다.)
package org.example.config;
import org.example.App;
import org.example.controller.OwnerController;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@ComponentScan(basePackageClasses = App.class)
@EnableAspectJAutoProxy
public class BeanConfig {
}
이렇게 간단하게 AOP를 테스트하여 보았습니다.^^
'Back-End > Springboot' 카테고리의 다른 글
SpringBoot에서 Vue.js를 연동하고 실행해보자 (0) | 2024.05.04 |
---|---|
[Spring boot] 간단한 회원가입 코드 구현해보기_2 (0) | 2024.04.07 |
[Spring boot] 간단한 회원가입 코드 구현해보기 (0) | 2024.03.13 |
[Spring boot] 간단한 회원가입 구현해보기 (2) | 2024.03.09 |
[Spring boot] war배포시 404 ERROR 해결 방법 (8) | 2024.01.08 |