Skip to content
This repository was archived by the owner on Dec 13, 2020. It is now read-only.

Commit 5c87e63

Browse files
committed
Feat: AOP Example2 Init
- package example2
1 parent b598bca commit 5c87e63

File tree

6 files changed

+125
-1
lines changed

6 files changed

+125
-1
lines changed

README.md

+13-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@
2020
* 예: 로깅, 트랜잭션, 보안 등
2121
* 각각의 모듈의 주 목적 외에 필요한 부가적인 기능들
2222

23+
### AOP 는 언제 사용되는가
24+
* 성능 검사
25+
* 트랜잭션 처리
26+
* 로깅
27+
* 예외 반환
28+
* 검증
29+
실 예로, ```@Transactional, @Cache``` 같은 어노테이션들은 AOP 를 활용하여 동작합니다.
30+
2331
### AOP 의 장점
2432
* 애플리케이션 전체에 흩어진 공통 기능이 하나의 장소에서 관리된다는 점
2533
* 다른 서비스 모듈들이 본인의 목적에만 충실하고 그외 사항들은 신경쓰지 않아도 된다는 점
@@ -44,15 +52,18 @@
4452
* 실질적으로 부가기능을 담은 구현체를 말합니다.
4553
* 타겟 오브젝트에 종속되지 않기 때문에 순수하게 **부가기능에만 집중**할 수 있습니다.
4654
* 애스펙트가 **무엇****언제** 할지를 정의하고 있습니다.
55+
* 각 JoinPoint 에 삽입되어 동작할 수 있는 코드
4756

4857
### 포인트컷 (PointCut)
4958
* 부가기능이 적용될 대상(메소드)를 선정하는 방법을 뜻합니다.
5059
* 즉, 어드바이스를 적용할 조인포인트를 선별하는 기능을 정의한 모듈을 말합니다.
60+
* 어떤 클래스의 어느 JoinPoint 를 사용할 것인지 결정
5161

5262
### 조인포인트 (JoinPoint)
5363
* 어드바이스가 적용될 수 있는 위치를 뜻합니다.
5464
* 다른 AOP 프레임워크와 달리 Spring 에서는 **메소드 조인포인트만 제공** 하고 있습니다.
5565
* 따라서 Spring 프레임워크 내에서 조인포인트라 하면 메소드를 가리킨다고 생각해도 됩니다.
66+
* 모듈의 기능이 삽입되어 동작할 수 있는 실행 가능한 특정 위치
5667

5768
### 프록시 (Proxy)
5869
* 타겟을 감싸서 타겟의 요청을 대신 받아주는 Wrapping 오브젝트입니다.
@@ -64,8 +75,9 @@
6475

6576
### 위빙 (Weaving)
6677
* 지정된 객체에 애스펙트를 적용하여 새로운 프록시 객체를 생성하는 과정을 말합니다.
78+
* PointCut 에 의해 결정된 JoinPoint 에 지정된 Advice 를 삽입하는 과정 (CrossCutting)
6779
* 예를 들어, A 라는 객체에 트랜잭션 애스펙트가 지정되어 있다고 가정합니다.
68-
* A 라는 객체가 실행되기 커넥션을 오픈하고 실행이 끝나면 커넥션을 종료하는 기능이 추가된 프록시 객체가 생성되고,
80+
* A 라는 객체가 실행되기 커넥션을 오픈하고 실행이 끝나면 커넥션을 종료하는 기능이 추가된 프록시 객체가 생성되고,
6981
이 프록시 객체가 앞으로 A 객체가 호출되는 시점에 사용됩니다.
7082
이때의 프록시 객체가 생성되는 과정을 **위빙** 이라고 생각하면 됩니다.
7183
* 컴파일 타임, 클래스 로드 타임, 런타임과 같은 시점에서 실행되지만, Spring AOP 는 런타임에서 프록시 객체가 생성됩니다.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package com.springboot.aop.example2;
2+
3+
import org.aspectj.lang.JoinPoint;
4+
import org.aspectj.lang.annotation.*;
5+
import org.slf4j.Logger;
6+
import org.slf4j.LoggerFactory;
7+
import org.springframework.stereotype.Component;
8+
9+
@Aspect
10+
@Component
11+
public class TestAspect {
12+
13+
/**
14+
* 로그를 찍는 Aspect
15+
*/
16+
17+
private static final Logger logger = LoggerFactory.getLogger(TestAspect.class);
18+
19+
@Before("execution(* com.springboot.aop.example2.service.*.*Aop(..))")
20+
public void onBeforeHandler(JoinPoint joinPoint) {
21+
logger.info("### onBeforeThing");
22+
}
23+
24+
@After("execution(* com.springboot.aop.example2.service.*.*Aop(..))")
25+
public void onAfterHandler(JoinPoint joinPoint) {
26+
logger.info("### onAfterHandler");
27+
}
28+
29+
@AfterReturning(pointcut = "execution(* com.springboot.aop.example2.service.*.*Aop(..))",
30+
returning = "str")
31+
public void onAfterReturningHandler(JoinPoint joinPoint, Object str) {
32+
logger.info("### @AfterReturning : {}", str);
33+
logger.info("### onAfterReturningHandler");
34+
}
35+
36+
@Pointcut("execution(* com.springboot.aop.example2.service.*.*Aop(..))")
37+
public void onPointcut(JoinPoint joinPoint) {
38+
logger.info("### onPointcut");
39+
}
40+
41+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.springboot.aop.example2.config;
2+
3+
import org.springframework.context.annotation.Configuration;
4+
import org.springframework.context.annotation.EnableAspectJAutoProxy;
5+
6+
@Configuration
7+
@EnableAspectJAutoProxy
8+
public class AspectJConfig {
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.springboot.aop.example2.controller;
2+
3+
import com.springboot.aop.example2.service.TestService;
4+
import org.springframework.web.bind.annotation.GetMapping;
5+
import org.springframework.web.bind.annotation.RestController;
6+
7+
@RestController
8+
public class TestController {
9+
10+
private TestService testService;
11+
12+
public TestController(TestService testService) {
13+
this.testService = testService;
14+
}
15+
16+
@GetMapping("noAop")
17+
public String noAop() {
18+
return testService.test();
19+
}
20+
21+
@GetMapping("aop")
22+
public String aop() {
23+
return testService.testAop();
24+
}
25+
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.springboot.aop.example2.service;
2+
3+
public interface TestService {
4+
5+
String test();
6+
7+
String testAop();
8+
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package com.springboot.aop.example2.service.impl;
2+
3+
import com.springboot.aop.example2.service.TestService;
4+
import org.slf4j.Logger;
5+
import org.slf4j.LoggerFactory;
6+
import org.springframework.stereotype.Service;
7+
8+
@Service
9+
public class TestServiceImpl implements TestService {
10+
11+
private static final Logger logger = LoggerFactory.getLogger(TestServiceImpl.class);
12+
13+
@Override
14+
public String test() {
15+
String msg = "Hello, Spring Boot No AOP";
16+
logger.info("***" + msg);
17+
return msg;
18+
}
19+
20+
@Override
21+
public String testAop() {
22+
String msg = "Hello, Spring Boot AOP";
23+
logger.info("***" + msg);
24+
return msg;
25+
}
26+
27+
}

0 commit comments

Comments
 (0)