스프링의 양대 산맥 중 하나인 AOP에 대해 배워보자!!!
프로그래밍 패러다임의 한 종류
OOP - Object Oriented Programming - 객체 지향 프로그래밍
AOP - Aspect Oriented Programming - 관점 지향 프로그래밍
AOP
0) Aspect
구현해야할 핵심 비지니스 로직은 아니지만, 개발할 때의 관심사 (횡단관심사 Cross-Concern) (성능/속도, 자원사용효율성, 트랜잭션(All or Nothing), 로깅, 보안 등)
1) Advice
횡단 관심사(Cross-Concern)를 실제 구현한 객체 (ex) 트랜잭션 처리)
2) Target
핵심 비지니스 로직이 구현된 서비스 객체 (@Service, 비지니스 계층의 서비스) => 관심사들을 적용할 대상!
3) Jointpoint
Target 객체가 가지고 있는 메소드들 (ex) transfer 메소드 - 계좌이체)
4) Proxy (Target 객체 + Advice)
Target의 Joinpoint 수행시, 필요로하는 Advice들을 결합시켜 하나로 수행시키는 객체 (필수 조건 : 타입 메소드 모두 Target과 동일하게 갖추고 있어야함)
5) Pointcut
어느 Target의, 어느 JointPoint에 ,어떤Advice를 적용시킬지를 결정하는 방법(설정)
---
Advice의 종류
--
Pintcut
---
public interface SampleService {
public abstract Integer doAdd(String op1, String op2) throws Exception;
} // end interface
SampleService
@Log4j2
@NoArgsConstructor
@Service
// 이 서비스 객체가 바로 AOP에서 말하는 Target 객체를 의미함!!!
// Target 객체 : 핵심 비지니스 로직을 메소드로 구현해 놓은 객체
public class SampleServiceImpl implements SampleService {
@Override
// 이 메소드가 AOP에서 말하는 JointPoint 메소드임!!!
public Integer doAdd(String op1, String op2) throws Exception {
log.info("doAdd({}, {}) invoked.", op1, op2);
return Integer.parseInt(op1) + Integer.parseInt(op2);
} // doAdd
} // end class
SampleServiceImpl
@Log4j2
@NoArgsConstructor
@Aspect // Aspect를 구현한 것을 나타내기 위해 사용 (component scan을 통해 자동으로 빈으로 등록불가)
@Component // 스프링 빈으로 등록하기 위한 어노테이션 (AOP와는 무관)
public class LogAdvice { // POJO : Plain Old Java Object
// POINTCUT EXPRESSION 생성은, AsepectJ 언어에서 제공하는 함수를 이용
// 이 pointcut 설정함수 이름은 "execution()"
// 이 execution 함수를 호출시, pointcut 설정내역을 인자값으로 매개변수에 전달해야함
@Before( "execution( * org.zerock.myapp.service.*Service.*(..) )" )
// Service로 끝나는 모든 클래스의 모든 메서드의 모든 매개변수(..)에 적용
public void logBefore() {
log.trace("==============================");
log.trace("logBefore() invoked.");
log.trace("==============================");
} // logBefore
} // end class
LogAdvice
@Log4j2
@NoArgsConstructor
//JUnit5 방식
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = { "file:src/main/webapp/WEB-INF/spring/root-context.xml" })
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@TestInstance(Lifecycle.PER_CLASS)
public class SampleServiceTests {
// 주입
@Setter(onMethod_=@Autowired)
private SampleService service;
// 주입이 되었는지 1회성 전처리 과정을 통해 확인하자
@BeforeAll
void beforeAll() {
log.trace("beforeAll() invoked.");
// 주입이 되었는지 확인 (주입이 되었다면 null이 아님)
assertNotNull(this.service);
log.info("\t+ this.service : {}", this.service);
log.info("\t+ type : {}", this.service.getClass().getName());
} // beforeAll
@Test
@Order(1)
@DisplayName("1. SampleService.testDoAdd")
@Timeout(value = 10, unit = TimeUnit.SECONDS)
void testDoAdd() throws Exception {
log.trace("testDoAdd() invoked.");
int result = this.service.doAdd("100", "200");
log.info("\t+ result : {}", result);
} // testDoAdd
} // end class
SampleServiceTests
logAdvice가 먼저 실행되어 로그를 찍어준다 (인터셉터와 유사한 역할)
이로서 개발자는 핵심 로직에 집중할 수 있다.
---
'국비학원' 카테고리의 다른 글
[국비지원] KH 정보교육원 116일차 (0) | 2022.09.14 |
---|---|
[국비지원] KH 정보교육원 115일차 (0) | 2022.09.13 |
[국비지원] KH 정보교육원 113일차 (0) | 2022.09.07 |
[국비지원] KH 정보교육원 110-112일차 (0) | 2022.09.05 |
[국비지원] KH 정보교육원 109일차 (0) | 2022.09.05 |