ํ์คํ ์น๐ ๊ฐ๋ฐ์ ์ง๋ง์ ๐ง๐ฝโ๐ป
โ ์ธ๊ณต์ง๋ฅ ๊ด์ฌ ๐ค
Categories
-
โฃ
โถ COMPUTER_SCIENCE
๐: 7 -
โฃ
โถ WEB
๐: 3 -
โฃ
โถ ETC
๐: 3-
โ
โฃ
ETCS
๐: 10 -
โ
โฃ
SUBBRAIN ๊ฐ๋ฐ๊ธฐ
๐: 5 -
โ
โ
YOS ๊ฐ๋ฐ๊ธฐ
๐: 1
-
โ
โฃ
-
โ
โถ AI
๐: 9-
โฃ
AITOOLS
๐: 3 -
โฃ
CV
๐: 2 -
โฃ
DEEP_LEARNING
๐: 1 -
โฃ
DATA_VIS
๐: 2 -
โฃ
GRAPH
๐: 1 -
โฃ
LIGHTWEIGHT
๐: 1 -
โฃ
MATH
๐: 1 -
โฃ
NLP
๐: 3 -
โ
STRUCTURED_DATA
๐: 2
-
โฃ
Spring5 ์ ๋ฌธ-AOP
AOP(Aspect Oriented Programming)
_ ์ด๋ณด ์น ๊ฐ๋ฐ์๋ฅผ ์ํ ์คํ๋ง 5 ํ๋ก๊ทธ๋๋ฐ ์ ๋ฌธ _์ ์คํ๋ง ์ธ ์ก์ ์ ๋ด์ฉ์ ๋ฐํ์ผ๋ก ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
AOP(Aspect Oriented Programming, ๊ธฐ๋ฅ ์งํฅ ํ๋ก๊ทธ๋๋ฐ)์ ์ฌ๋ฌ ๊ฐ์ฒด์ ๊ณตํต์ผ๋ก ์ ์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ ๋ถ๋ฆฌํ์ฌ ์ฌ์ฌ์ฉ์ฑ์ ๋์ฌ์ฃผ๋ ํ๋ก๊ทธ๋๋ฐ ๊ธฐ๋ฒ์ด๋ค.
์ด๋ ํต์ฌ ๊ธฐ๋ฅ๊ณผ ๊ณตํต ๊ธฐ๋ฅ์ ๊ตฌ๋ถํด ๊ตฌํํ๋ ๋ฐฉ๋ฒ์ ํ๋ก์ ํจํด์ ์ด์ฉํ๋ฉฐ, ๊ตฌํ ๋ฐฉ๋ฒ์ ๋ฐ๋ผ ์ธ ๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ๋๋๋ค.
- ์ปดํ์ผ ์์ ์ ์ฝ๋์ ๊ณตํต ๊ธฐ๋ฅ ์ฝ์ -> AspectJ ๊ฐ์ AOP ์ ์ฉ ๋๊ตฌ๋ก ๊ตฌํ
- ํด๋์ค ๋ก๋ฉ ์์ ์ ๋ฐ์ดํธ ์ฝ๋์ ๊ณตํต ๊ธฐ๋ฅ ์ฝ์ -> AspectJ ๊ฐ์ AOP ์ ์ฉ ๋๊ตฌ๋ก ๊ตฌํ
- ๋ฐํ์์ ํ๋ก์ ๊ฐ์ฒด ์์ฑํด ๊ณตํต ๊ธฐ๋ฅ ์ฝ์ -> ์คํ๋ง์ ์๋ ์์ฑ ํ๋ก์ ๊ฐ์ฒด๋ก ๊ตฌํ
์ฐ๋ฆฐ ์ด ์ค์ 3๋ฒ์งธ ๋ฐฉ๋ฒ์ ์์๋ณผ ๊ฒ์ด๋ค.
ํ๋ก์ ํจํด
์๋ ์์ ์ฝ๋์ ๊ฐ์ด ํต์ฌ ๊ธฐ๋ฅ์ ์คํ์ ๋ค๋ฅธ ๊ฐ์ฒด์ ์์ํ๊ณ ๋ถ๊ฐ์ ์ธ ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ๊ฐ์ฒด๋ฅผ ํ๋ก์(Proxy)๋ผ๊ณ ํ๋ฉฐ, ์ค์ ํต์ฌ ๊ธฐ๋ฅ์ ์คํํ๋ ๊ฐ์ฒด๋ ๋์ ๊ฐ์ฒด๋ผ๊ณ ํ๋ค.
์ด๋ฅผ ํตํด ๊ณตํต ๊ธฐ๋ฅ ์ฝ๋๋ฅผ ์ฌ์ฌ์ฉํ๊ณ ์์ ํ๊ธฐ ์ฌ์ฐ๋ฉฐ ๊ฐ๋ ์ฑ ์ข์ ์ฝ๋๋ฅผ ๋ง๋ค์ด ๋ผ ์ ์๋ค.
ํ๋ก์ ํจํด ์์
public interface Printer {
public String print(String words);
}
public class TargetObject implements Printer{
@Override
public String print(String words) {
System.out.printf("TargetObject.print()");
return result;
}
}
public class ProxyObject implements Printer {
private Printer delegate;
public ProxyObject(Printer delegate) {
this.delegate = delegate;
}
@Override
public String print(String words) {
System.out.printf("Before TargetObject.print()");
String result = delegate.print(words);
System.out.printf("After TargetObject.print()");
return result;
}
}
public class MainProxy {
public static void main(String[] args) {
ProxyObject proxy = new ProxyObject(new TargetObject());
System.out.println("%s", proxy.print("result"));
}
}
/* console:
Before TargetObject.print()
TargetObject.print()
After TargetObject.print()
result
*/
AOP ๊ตฌํ
์คํ๋ง์ aspectjweaver
์์กด์ ์ถ๊ฐํ๋ฉด AOP๋ฅผ ์ฝ๊ฒ ๊ตฌํํ ์ ์๋ค.
์คํ๋ง AOP๋ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์๋์ผ๋ก ์์ฑํด ์ฃผ๋ฉฐ, ๋ค์๊ณผ ๊ฐ์ ์ฉ์ด๊ฐ ์กด์ฌํ๋ค.
Aspect
: ๊ณตํต์ผ๋ก ์ ์ฉํ ๊ธฐ๋ฅ, ๋ฉ์๋, ์์๋ก ํธ๋์ญ์ , ๋ณด์, ์บ์, ์ฑ๋ฅ ๋ชจ๋ํฐ๋ง ๋ฑ์ด ์์Advice
:Aspect
์ ์ ์ฉํ ์์ , ๋ฉ์๋ ์ (Before), ํ(After), ์ ์ ์๋ ํ(After Returning), ์ค๋ฅ ํ(After Throwing) ๋ฑ์ด ์กด์ฌํ์ง๋ง ๋ชจ๋ ์์ ์ ์์ ๋กญ๊ฒ ์ ์ฉ๊ฐ๋ฅํAround Adivce
๋ฅผ ๊ฐ์ฅ ์์ฃผ ์ฌ์ฉํ๋ค.Joinpoint
:Advice
๋ฅผ ์ ์ฉ ๊ฐ๋ฅํ ๋ถ๋ถ, ๋ฉ์๋, ํ๋ ๊ฐ ๋ณ๊ฒฝ ๋ฑ์ด ์กด์ฌํ์ง๋ง ์คํ๋ง์ ๋ฉ์๋์๋ง ์ ์ฉ ๊ฐ๋ฅํ๋ค.Pointcut
: ํด๋น ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ ์ฉํ ํด๋์ค, ๋น ๊ฐ์ฒด ๋ฑ์ ๋ฒ์๋ฅผ ์ง์ Weaving
: ์ด๋ฌํ AOP๋ฅผ ํน์ ๊ฐ์ฒด์ ์ค์ ํด์ฃผ๋ ํ์๋ฅผ ์๋ฏธ
Aspect ํด๋์ค ๊ตฌํ
์คํ๋ง AOP์์ ๊ฐ์ฅ ์์ฃผ ์ฌ์ฉ๋๋ Around Advice๋ฅผ ๊ธฐ์ค์ผ๋ก ๋ค์๊ณผ ๊ฐ์ด ๊ตฌํํ๋ฉด ๋๋ค.
- Aspect๋ก ์ฌ์ฉํ ํด๋์ค์
@Aspect
์ด๋ ธํ ์ด์ ์ ์ฉ @Pointcut
์ด๋ ธํ ์ด์ ์ผ๋ก ๊ณตํต ๊ธฐ๋ฅ์ ์ ์ฉํ ๊ฐ์ฒด๋ฅผ ์ง์ - ๊ณตํต ๊ธฐ๋ฅ ๊ตฌํ ๋ฉ์๋์
@Around
์ด๋ ธํ ์ด์ ์ ์ฉํ์ฌ ๋์ ๋ฉ์๋ ์ ํ ์คํ์ ๊ด๋ จํ ๋ก์ง ์์ฑ
package aspect;
import java.util.Arrays;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
@Aspect //ํ๋ก์ ๊ฐ์ฒด ๊ตฌํ์ ์ํ Aspect ๊ฐ์ฒด๋ก ์ง์
@Order(1) // ์ฌ๋ฌ AOP ์ ์ฉ์ ๋ฉ์๋๋ฅผ ๊ฐ์ ์ฐ์ ์์, ๋ฎ์์๋ก ๋จผ์ ๊ฐ์ผ๋ค.
public class ExeTimeAspect {
@Pointcut("execution(public * chap07..*(..))") // chap07 ํจํค์ง ๋ด์ ๋ชจ๋ ํผ๋ธ๋ฆญ ๋ฉ์๋๋ค์ด ๋์
private void publicTarget() {
}
@Around("publicTarget()") // ์๋ Around Adivce ๊ธฐ๋ฅ์ publicTarget์์ ์ค์ ํ ๋ฒ์์๋ง ์ ์ฉ๋๋ค.
public Object measure(ProceedingJoinPoint joinPoint) throws Throwable { // ๊ณตํต ๊ธฐ๋ฅ ๊ตฌํ ๋ฉ์๋, ๋ฆฌํด ํ์
์ ๋ชจ๋ ๊ฐ์ ์์ฐ๋ฅผ ์ ์๊ฒ ์์ ํ์
์ธ Object
long start = System.nanoTime();
try {
Object result = joinPoint.proceed(); // ์ ์ฉ ๋์ ๋ฉ์๋ ์คํ, ProceedingJoinPoint์ ๋ํด์ ์๋ ์ชฝ์ ์ค๋ช
return result;
} finally {
long finish = System.nanoTime();
Signature sig = joinPoint.getSignature();
System.out.printf("%s.%s(%s) ์คํ ์๊ฐ : %d ns\n",
joinPoint.getTarget().getClass().getSimpleName(), // ์ ์ฉ ๋์ ๋ฉ์๋ ์๊ทธ๋์ฒ ์ ๋ณด
sig.getName(), Arrays.toString(joinPoint.getArgs()),
(finish - start));
}
}
}
pointcut ๋ฉ์๋ ์ค์ ์ ์ํ ๋ฒ์ ์ง์ ์ ์ํด ์ฌ์ฉ๋จ
@Around ์ด๋
ธํ
์ด์
์์ ์ง์ ๋ช
์ํด๋ ๋ฒ์๊ฐ ์ง์ ๋์ง๋ง, ์ ์์์ ๊ฐ์ด PublicTarget() ์ฒ๋ผ @Pointcut ๋ฉ์๋๋ฅผ ์ง์ ํด์ฃผ๋ฉด ๋ค๋ฅธ ํจํค์ง์์ ์ํฌํธํ๊ฑฐ๋ @Around("ํจํค์ง๋ช
.Aspect๊ฐ์ฒด.publicTarget()")
์ฒ๋ผ ์ฌํ์ฉ ๊ฐ๋ฅ
execution(์์์ดํจํด? ๋ฆฌํดํ์
ํจํด ํด๋์ค์ด๋ฆํจํด?๋ฉ์๋์ด๋ฆํจํด(ํ๋ผ๋ฏธํฐํจํด))
*: ๋ชจ๋ ๊ฐ
.. : 0๊ฐ ์ด์
ProceedingJoinPoint
๊ฐ์ฒด์ ์ธํฐํ์ด์ค
proceed()
: ์ง์ ๋ฉ์๋๊ฐ ์คํ๋๋ ์์ ์ ์๋ฏธ, ๋ฉ์๋ ๊ฒฐ๊ณผ๊ฐ์ ๋ฆฌํดํ๋ฉฐ, ์ด๋ฅผ ๋ค์ ๋ฆฌํดํด์ค์ผ ํจ.getSignature()
: ํธ์ถ๋๋ ๋ฉ์๋์ ๋ํ ์๊ทธ๋์ฒ ๊ฐ์ฒด- ๋ฆฌํด ๊ฐ์ธ
Signature
๊ฐ์ฒด๋ก ๋ถํฐ ๋ฉ์๋๋ช (getName()), ์๊ทธ๋์ฒ ์ ๋ณด(toLongString()) ๋ฑ์ ๊ตฌํจ
- ๋ฆฌํด ๊ฐ์ธ
getTarget()
: ๋์ ๊ฐ์ฒด ์ธ์คํด์คgetArgs()
: ๋์ ๋ฉ์๋ ํ๋ฆฌ๋ฏธํฐ
Aspect ํด๋์ค ์ ์ฉ
์ดํ ์์ฑํ ํด๋์ค๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ๊ตฌ์ฑ ํด๋์ค์ ๋ฑ๋กํ๋ฉด ์ ์ฉ๋๋ค.
//...
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@Configuration
@EnableAspectJAutoProxy // ํ์ Enable๋ฅ ์ด๋
ธํ
์ด์
, AOP ๊ฐ์ฒด ์ฌ์ฉ์ ์ํ ์ค์ ๋น ๊ฐ์ฒด๋ค์ ์๋์ผ๋ก ๋ฑ๋กํด์ค
public class AppCtx {
@Bean
public ExeTimeAspect exeTimeAspect() { // ์ฐ๋ฆฌ๊ฐ ๋ง๋ Aspect
return new ExeTimeAspect();
}
@Bean
public Calculator calculator() {
return new RecCalculator();
}
//...
์ดํ ๋ค์๊ณผ ๊ฐ์ด ๋น ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ ํด๋์ค๋ฅผ ํ์ธํด๋ณด๋ฉด ์๋ ์์ฑ๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์์ฑ๋์์์ ์ ์ ์๋ค.
Calculator cal = ctx.getBean("calculator", Calculator.class);
long fiveFact = cal.factorial(5);
System.out.println("cal.factorial(5) = " + fiveFact);
System.out.println(cal.getClass().getName()); // com.sum.proxy.%Proxy17 => RecCalculator ํด๋์ค๊ฐ ์๋๋ผ ์๋ ์์ฑ๋ ํ๋ก์ ๊ฐ์ฒด
ctx.close();
/* console:
RecCalculator.factorial([5]) ์คํ ์๊ฐ: 50201 ns
cal.factorial(5)=120
com.sum.proxy.%Proxy17
*/
์ด๋ %Proxy17
์ ํ์
์ ๋ฉ์๋์ ๋ฆฌํด ํ์
์ธ Calculator
๋ฅผ ์์๋ฐ์ ์์ฑ๋จ
RecCalculator
ํด๋์ค๋ฅผ ์์๋ฐ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์ด์ฉํด ์์ฑํ๊ณ ์ถ๋ค๋ฉด
์ด๋
ธํ
์ด์
@EnableAspectJAutoProxy(proxyTargetClass = true)
๋ก ์ค์ ํ๋ฉด ๋ฉ์๋ ๋ฆฌํดํ์
์ด ์๋, ์ค์ ๊ฒฐ๊ณผ๊ฐ์ ํ์
์ผ๋ก ์ค์ ๋๋ค.
_articles/web/backend/Spring/Spring5 ์ ๋ฌธ-AOP.md