Skip to content

Commit b840a18

Browse files
authored
Merge pull request #7 from chhs2131/SpringMVC
AOP 및 자바Proxy 예제 추가
2 parents d4662a8 + ee7d8cc commit b840a18

File tree

13 files changed

+774
-0
lines changed

13 files changed

+774
-0
lines changed

aop-example/.gitignore

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
HELP.md
2+
.gradle
3+
build/
4+
!gradle/wrapper/gradle-wrapper.jar
5+
!**/src/main/**/build/
6+
!**/src/test/**/build/
7+
8+
### STS ###
9+
.apt_generated
10+
.classpath
11+
.factorypath
12+
.project
13+
.settings
14+
.springBeans
15+
.sts4-cache
16+
bin/
17+
!**/src/main/**/bin/
18+
!**/src/test/**/bin/
19+
20+
### IntelliJ IDEA ###
21+
.idea
22+
*.iws
23+
*.iml
24+
*.ipr
25+
out/
26+
!**/src/main/**/out/
27+
!**/src/test/**/out/
28+
29+
### NetBeans ###
30+
/nbproject/private/
31+
/nbbuild/
32+
/dist/
33+
/nbdist/
34+
/.nb-gradle/
35+
36+
### VS Code ###
37+
.vscode/

aop-example/README.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# AOP 예시
2+
관점 지향 프로그래밍 예제입니다. 순사 자바 Proxy에 대해 먼저 소개하고, Spring이 제공하는 AOP에 대해 살펴봅니다.
3+
4+
5+
</br>
6+
7+
## 순수 자바의 Proxy
8+
```java
9+
package org.example.aopexample;
10+
11+
import java.lang.reflect.InvocationHandler;
12+
import java.lang.reflect.Proxy;
13+
import org.example.aopexample.job.Worker;
14+
15+
public class WorkerProxy {
16+
private Worker worker;
17+
18+
public WorkerProxy(Worker worker) {
19+
this.worker = worker;
20+
}
21+
22+
public Worker getWorker() {
23+
return (Worker) Proxy.newProxyInstance(
24+
Worker.class.getClassLoader(),
25+
new Class[]{Worker.class},
26+
workerHandler()
27+
);
28+
}
29+
30+
private InvocationHandler workerHandler() {
31+
return (proxy, method, args) -> {
32+
System.out.println("====================================================================================");
33+
System.out.println("관리자: 일해라! 이놈아!");
34+
long start = System.currentTimeMillis();
35+
36+
Object result = method.invoke(worker, args);
37+
38+
long end = System.currentTimeMillis();
39+
System.out.println("관리자: 일하는데 " + (double) (end-start)/1000 + "초가 걸렷네!!");
40+
System.out.println("====================================================================================");
41+
return result;
42+
};
43+
}
44+
}
45+
```
46+
47+
48+
</br>
49+
50+
### 실행결과
51+
```javascript
52+
요리사: 요리을 합니다.
53+
요리사: 요리완료!
54+
====================================================================================
55+
관리자: 일해라! 이놈아!
56+
개발자: 코딩을 합니다.
57+
개발자: 코딩완료!
58+
관리자: 일하는데 1.005초가 걸렷네!!
59+
====================================================================================
60+
====================================================================================
61+
관리자: 일해라! 이놈아!
62+
요리사: 요리을 합니다.
63+
요리사: 요리완료!
64+
관리자: 일하는데 1.501초가 걸렷네!!
65+
====================================================================================
66+
```
67+
68+
</br>
69+
</br>
70+
</br>
71+
72+
## 스프링 AOP
73+
74+
### 의존성 추가
75+
```groovy
76+
dependencies {
77+
/* 스프링 AOP 사용을 위해 추가 */
78+
implementation 'org.springframework.boot:spring-boot-starter-aop'
79+
}
80+
```
81+
82+
83+
</br>
84+
85+
### Controller
86+
```java
87+
@RestController
88+
public class WorkerController {
89+
@GetMapping("/cook")
90+
void cook() {
91+
final Cooker cooker = new Cooker();
92+
cooker.work();
93+
}
94+
95+
@GetMapping("/coding")
96+
void coding() {
97+
final Programmer programmer = new Programmer();
98+
programmer.work();
99+
}
100+
}
101+
```
102+
103+
</br>
104+
105+
### AOP Class
106+
```java
107+
package org.example.aopexample;
108+
109+
import org.aspectj.lang.annotation.Aspect;
110+
import org.aspectj.lang.annotation.Before;
111+
import org.aspectj.lang.annotation.After;
112+
import org.aspectj.lang.annotation.Around;
113+
import org.aspectj.lang.ProceedingJoinPoint;
114+
import org.springframework.stereotype.Component;
115+
116+
@Aspect
117+
@Component
118+
public class WorkerAspect {
119+
120+
// WorkerController의 cook 메소드를 실행하기 전에 실행
121+
@Before("execution(* org.example.aopexample.spring.WorkerController.cook(..))")
122+
public void beforeCooking() {
123+
System.out.println("요리 재료를 준비합니다...");
124+
}
125+
126+
// WorkerController의 coding 메소드를 실행한 후에 실행
127+
@After("execution(* org.example.aopexample.spring.WorkerController.coding(..))")
128+
public void afterCoding() {
129+
System.out.println("리팩토링을 진행합니다...");
130+
}
131+
132+
// WorkerController에 있는 모든 메소드 실행에 AOP를 지정
133+
@Around("execution(* org.example.aopexample.spring.WorkerController.*(..))")
134+
public Object aroundWorkerActivities(ProceedingJoinPoint joinPoint) throws Throwable {
135+
System.out.println("====================================================================================");
136+
System.out.println("관리자: 일해라! 이놈아!" + joinPoint.getSignature().getName());
137+
long start = System.currentTimeMillis();
138+
139+
Object result = joinPoint.proceed(); // Proceed with the original method call
140+
141+
long end = System.currentTimeMillis();
142+
System.out.println("관리자: 일하는데 " + (double) (end-start)/1000 + "초가 걸렷네!!" + joinPoint.getSignature().getName());
143+
System.out.println("====================================================================================");
144+
return result;
145+
}
146+
}
147+
```
148+
149+
</br>
150+
151+
### 실행결과
152+
```javascript
153+
. ____ _ __ _ _
154+
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
155+
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
156+
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
157+
' |____| .__|_| |_|_| |_\__, | / / / /
158+
=========|_|==============|___/=/_/_/_/
159+
:: Spring Boot :: (v3.2.3)
160+
161+
2024-03-12T02:04:49.750+09:00 INFO 12397 --- [aop-example] [ main] o.e.aopexample.AopExampleApplication : Starting AopExampleApplication using Java 17.0.4.1 with PID 12397 (/Users/hyeon/Documents/GitHub/SpringExample/aop-example/build/classes/java/main started by hyeon in /Users/hyeon/Documents/GitHub/SpringExample/aop-example)
162+
2024-03-12T02:04:49.752+09:00 INFO 12397 --- [aop-example] [ main] o.e.aopexample.AopExampleApplication : The following 1 profile is active: "local"
163+
2024-03-12T02:04:50.091+09:00 INFO 12397 --- [aop-example] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)
164+
2024-03-12T02:04:50.095+09:00 INFO 12397 --- [aop-example] [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
165+
2024-03-12T02:04:50.095+09:00 INFO 12397 --- [aop-example] [ main] o.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/10.1.19]
166+
2024-03-12T02:04:50.112+09:00 INFO 12397 --- [aop-example] [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
167+
2024-03-12T02:04:50.112+09:00 INFO 12397 --- [aop-example] [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 344 ms
168+
2024-03-12T02:04:50.256+09:00 INFO 12397 --- [aop-example] [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path ''
169+
2024-03-12T02:04:50.262+09:00 INFO 12397 --- [aop-example] [ main] o.e.aopexample.AopExampleApplication : Started AopExampleApplication in 0.631 seconds (process running for 4.865)
170+
2024-03-12T02:04:53.217+09:00 INFO 12397 --- [aop-example] [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring DispatcherServlet 'dispatcherServlet'
171+
2024-03-12T02:04:53.217+09:00 INFO 12397 --- [aop-example] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Initializing Servlet 'dispatcherServlet'
172+
2024-03-12T02:04:53.219+09:00 INFO 12397 --- [aop-example] [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 2 ms
173+
====================================================================================
174+
관리자: 일해라! 이놈아!cook
175+
요리 재료를 준비합니다...
176+
요리사: 요리을 합니다.
177+
요리사: 요리완료!
178+
관리자: 일하는데 1.505초가 걸렷네!!cook
179+
====================================================================================
180+
====================================================================================
181+
관리자: 일해라! 이놈아!coding
182+
개발자: 코딩을 합니다.
183+
개발자: 코딩완료!
184+
리팩토링을 진행합니다...
185+
관리자: 일하는데 1.005초가 걸렷네!!coding
186+
====================================================================================
187+
```
188+

aop-example/build.gradle

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
plugins {
2+
id 'java'
3+
id 'org.springframework.boot' version '3.2.3'
4+
id 'io.spring.dependency-management' version '1.1.4'
5+
}
6+
7+
group = 'org.example'
8+
version = '0.0.1-SNAPSHOT'
9+
10+
java {
11+
sourceCompatibility = '17'
12+
}
13+
14+
configurations {
15+
compileOnly {
16+
extendsFrom annotationProcessor
17+
}
18+
}
19+
20+
repositories {
21+
mavenCentral()
22+
}
23+
24+
dependencies {
25+
/* 스프링 AOP 사용을 위해 추가 */
26+
implementation 'org.springframework.boot:spring-boot-starter-aop'
27+
28+
implementation 'org.springframework.boot:spring-boot-starter-web'
29+
compileOnly 'org.projectlombok:lombok'
30+
annotationProcessor 'org.projectlombok:lombok'
31+
testImplementation 'org.springframework.boot:spring-boot-starter-test'
32+
}
33+
34+
tasks.named('test') {
35+
useJUnitPlatform()
36+
}

0 commit comments

Comments
 (0)