๐ก ๊น์ํ๋์ ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์
๋๋ค.
@Aspect ํ๋ก์ ์ ์ฉ
์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ์ ํ๋ก์๋ฅผ ์ ์ฉํ๋ ค๋ฉด ํฌ์ธํธ์ปท๊ณผ ์ด๋๋ฐ์ด์ค๋ก ๊ตฌ์ฑ๋์ด ์๋ ์ด๋๋ฐ์ด์ ( Advisor )๋ฅผ ๋ง๋ค์ด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ฉด ๋๋ค. ๊ทธ๋ฌ๋ฉด ๋๋จธ์ง๋ ์์ ๋ฐฐ์ด ์๋ ํ๋ก์ ์์ฑ๊ธฐ๊ฐ ๋ชจ๋ ์๋์ผ๋ก ์ฒ๋ฆฌํด์ค๋ค. ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋ ์ด๋๋ฐ์ด์ ๋ค์ ์ฐพ๊ณ , ์คํ๋ง ๋น๋ค์ ์๋์ผ๋ก ํ๋ก์๋ฅผ ์ ์ฉํด์ค๋ค. (๋ฌผ๋ก ํฌ์ธ ํธ์ปท์ด ๋งค์นญ๋๋ ๊ฒฝ์ฐ์ ํ๋ก์๋ฅผ ์์ฑํ๋ค.)
์คํ๋ง์ @Aspect ์ ๋ ธํ ์ด์ ์ผ๋ก ๋งค์ฐ ํธ๋ฆฌํ๊ฒ ํฌ์ธํธ์ปท๊ณผ ์ด๋๋ฐ์ด์ค๋ก ๊ตฌ์ฑ๋์ด ์๋ ์ด๋๋ฐ์ด์ ์์ฑ ๊ธฐ๋ฅ์ ์ง์ํ๋ค. ์ง๊ธ๊น์ง ์ด๋๋ฐ์ด์ ๋ฅผ ์ง์ ๋ง๋ค์๋ ๋ถ๋ถ์ @Aspect ์ ๋ ธํ ์ด์ ์ ์ฌ์ฉํด์ ๋ง๋ค์ด๋ณด์.
@Slf4j
@Aspect
public class LogTraceAspect {
private final LogTrace logTrace;
public LogTraceAspect(LogTrace logTrace) {
this.logTrace = logTrace;
}
@Around("execution(* hello.proxy.app..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {
TraceStatus status = null;
try {
String message = joinPoint.getSignature().toShortString();
status = logTrace.begin(message);
//๋ก์ง ํธ์ถ
Object result = joinPoint.proceed();
logTrace.end(status);
return result;
} catch (Exception e) {
logTrace.exception(status, e);
throw e;
}
}
}
- @Aspect: ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ์ ์ฉํ ๋ ํ์ํ๋ค
- @Around("execution(* hello.proxy.app..*(..))")
- @Around์ ๊ฐ์ ํฌ์ธํธ์ปท ํํ์์ ๋ฃ๋๋ค. ํํ์์ AspectJ ํํ์์ ์ฌ์ฉํ๋ค.
- @Around์ ๋ฉ์๋๋ ์ด๋๋ฐ์ด์ค( Advice )๊ฐ ๋๋ค
- ProceedingJoinPoint joinPoint: ์ด๋๋ฐ์ด์ค์์ ์ดํด๋ณธ MethodInvocation invocation๊ณผ ์ ์ฌํ ๊ธฐ๋ฅ์ด๋ค. ๋ด๋ถ์ ์ค์ ํธ์ถ ๋์, ์ ๋ฌ ์ธ์, ๊ทธ๋ฆฌ๊ณ ์ด๋ค ๊ฐ์ฒด์ ์ด๋ค ๋ฉ์๋๊ฐ ํธ์ถ๋์๋์ง ์ ๋ณด๊ฐ ํฌํจ๋์ด ์๋ค
- joinPoint.proceed(): ์ค์ ํธ์ถ ๋์( target )์ ํธ์ถํ๋ค.
๊ฐ๋จํ๊ฒ ์ ๋ฆฌํ๋ฉด @Around์์ ์ค์ ํ๊ฒ ํฌ์ธํธ์ปท์ด๊ณ execute ๋ด๋ถ ๋ก์ง์ ์ด๋๋ฐ์ด์ค๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ๋์ ํฉ์น๋ฉด ์ด๋๋ฐ์ด์ ๋ผ๊ณ ์ดํดํ๋ฉด ๋๋ค.
AopConfig
@Configuration
@Import({AppV1Config.class, AppV2Config.class})
public class AopConfig {
@Bean
public LogTraceAspect logTraceAspect(LogTrace logTrace) {
return new LogTraceAspect(logTrace);
}
}
- @Import({AppV1Config.class, AppV2Config.class}): V1, V2 ์ ํ๋ฆฌ์ผ์ด์ ์ ์๋์ผ๋ก ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด์ผ ๋์ํ๋ค
- @Bean logTraceAspect(): @Aspect๊ฐ ์์ด๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก์ ํด์ค์ผ ํ๋ค. ๋ฌผ๋ก LogTraceAspect์ @Component` ์ ๋ ธํ ์ด์ ์ ๋ถ์ฌ์ ์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํด์ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด๋ ๋๋ค.
ProxyApplication
@Import(AopConfig.class)
@SpringBootApplication(scanBasePackages = "hello.proxy.app") //์ฃผ์
public class ProxyApplication {
public static void main(String[] args) {
SpringApplication.run(ProxyApplication.class, args);
}
@Bean
public LogTrace logTrace() {
return new ThreadLocalLogTrace();
}
}
@Aspect ํ๋ก์ - ์ค๋ช
์์ ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ฅผ ํ์ตํ ๋, ์๋ ํ๋ก์ ์์ฑ๊ธฐ( AnnotationAwareAspectJAutoProxyCreator )๋ Advisor๋ฅผ ์๋์ผ๋ก ์ฐพ์์์ ํ์ํ ๊ณณ์ ํ๋ก์๋ฅผ ์์ฑํ๊ณ ์ ์ฉํด์ค๋ค๊ณ ํ๋ค. ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ ์ฌ๊ธฐ์ ์ถ๊ฐ๋ก ํ๋์ ์ญํ ์ ๋ ํ๋๋ฐ, ๋ฐ๋ก @Aspect๋ฅผ ์ฐพ์์ ์ด๊ฒ์ Advisor๋ก ๋ง๋ค์ด์ค๋ค. ์ฝ๊ฒ ์ด์ผ๊ธฐํด์ ์ง๊ธ๊น์ง ํ์ตํ ๊ธฐ๋ฅ์ ๋ํด @Aspect๋ฅผ Advisor๋ก ๋ณํํด์ ์ ์ฅํ๋ ๊ธฐ๋ฅ๋ ํ๋ค. ๊ทธ๋์ ์ด๋ฆ ์์ AnnotationAware (์ ๋ ธํ ์ด์ ์ ์ธ์ํ๋)๊ฐ ๋ถ์ด ์๋ ๊ฒ์ด๋ค.

์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ 2๊ฐ์ง ์ผ์ ํ๋ค.
- @Aspect๋ฅผ ๋ณด๊ณ ์ด๋๋ฐ์ด์ (Advisor)๋ก ๋ณํํด์ ์ ์ฅํ๋ค.
- ์ด๋๋ฐ์ด์ ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก์๋ฅผ ์์ฑํ๋ค.
1. @Aspect๋ฅผ ์ด๋๋ฐ์ด์ ๋ก ๋ณํํด์ ์ ์ฅํ๋ ๊ณผ์

@Aspect๋ฅผ ์ด๋๋ฐ์ด์ ๋ก ๋ณํํด์ ์ ์ฅํ๋ ๊ณผ์ ์ ์์๋ณด์
- ์คํ: ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ๋ก๋ฉ ์์ ์ ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ฅผ ํธ์ถํ๋ค.
- ๋ชจ๋ @Aspect ๋น ์กฐํ: ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ ์คํ๋ง ์ปจํ ์ด๋์์ @Aspect ์ ๋ ธํ ์ด์ ์ด ๋ถ์ ์คํ๋ง ๋น์ ๋ชจ๋ ์กฐํํ๋ค.
- ์ด๋๋ฐ์ด์ ์์ฑ: @Aspect ์ด๋๋ฐ์ด์ ๋น๋๋ฅผ ํตํด @Aspect ์ ๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ด๋๋ฐ์ด์ ๋ฅผ ์์ฑํ๋ค.
- @Aspect ๊ธฐ๋ฐ ์ด๋๋ฐ์ด์ ์ ์ฅ: ์์ฑํ ์ด๋๋ฐ์ด์ ๋ฅผ @Aspect ์ด๋๋ฐ์ด์ ๋น๋ ๋ด๋ถ์ ์ ์ฅํ๋ค.
2. ์ด๋๋ฐ์ด์ ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ก์ ์์ฑ

์๋ ํ๋ก์ ์์ฑ๊ธฐ์ ์๋ ๊ณผ์ ์ ์์๋ณด์
1. ์์ฑ: ์คํ๋ง ๋น ๋์์ด ๋๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. (@Bean, ์ปดํฌ๋ํธ ์ค์บ ๋ชจ๋ ํฌํจ)
2. ์ ๋ฌ: ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ๋น ์ ์ฅ์์ ๋ฑ๋กํ๊ธฐ ์ง์ ์ ๋น ํ์ฒ๋ฆฌ๊ธฐ์ ์ ๋ฌํ๋ค
3-1. Advisor ๋น ์กฐํ: ์คํ๋ง ์ปจํ ์ด๋์์ Advisor ๋น์ ๋ชจ๋ ์กฐํํ๋ค.
3-2. @Aspect Advisor ์กฐํ: @Aspect ์ด๋๋ฐ์ด์ ๋น๋ ๋ด๋ถ์ ์ ์ฅ๋ Advisor๋ฅผ ๋ชจ๋ ์กฐํํ๋ค.
4. ํ๋ก์ ์ ์ฉ ๋์ ์ฒดํฌ: ์์ 3-1, 3-2์์ ์กฐํํ `Advisor` ์ ํฌํจ๋์ด ์๋ ํฌ์ธํธ์ปท์ ์ฌ์ฉํด์ ํด๋น ๊ฐ์ฒด๊ฐ ํ๋ก์๋ฅผ ์ ์ฉํ ๋์์ธ์ง ์๋์ง ํ๋จํ๋ค. ์ด๋ ๊ฐ์ฒด์ ํด๋์ค ์ ๋ณด๋ ๋ฌผ๋ก ์ด๊ณ , ํด๋น ๊ฐ์ฒด์ ๋ชจ๋ ๋ฉ์๋ ๋ฅผ ํฌ์ธํธ์ปท์ ํ๋ํ๋ ๋ชจ๋ ๋งค์นญํด๋ณธ๋ค. ๊ทธ๋์ ์กฐ๊ฑด์ด ํ๋๋ผ๋ ๋ง์กฑํ๋ฉด ํ๋ก์ ์ ์ฉ ๋์์ด ๋๋ค. ์๋ฅผ ๋ค์ด์ ๋ฉ์๋ ํ๋๋ง ํฌ์ธํธ์ปท ์กฐ๊ฑด์ ๋ง์กฑํด๋ ํ๋ก์ ์ ์ฉ ๋์์ด ๋๋ค.
5. ํ๋ก์ ์์ฑ: ํ๋ก์ ์ ์ฉ ๋์์ด๋ฉด ํ๋ก์๋ฅผ ์์ฑํ๊ณ ํ๋ก์๋ฅผ ๋ฐํํ๋ค. ๊ทธ๋์ ํ๋ก์๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค. ๋ง์ฝ ํ๋ก์ ์ ์ฉ ๋์์ด ์๋๋ผ๋ฉด ์๋ณธ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ ์๋ณธ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค
6. ๋น ๋ฑ๋ก: ๋ฐํ๋ ๊ฐ์ฒด๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋๋ค.
@Aspect์ ์ฐ๋ฉด ์คํ๋ง์ด @Aspect ๋ด๋ถ์ ์ฌ์ฉ๋ @Around(ํฌ์ธํธ์ปท)์ @Around๊ฐ ์ฐ์ธ ๋ฉ์๋(์ด๋๋ฐ์ด์ฆ)๋ฅผ ๋ณด๊ณ ์ด๋๋ฐ์ด์ ๋ฅผ ๋ง๋ ๋ค. @Aspect๋ก ๋ง๋ ๊ฒ๋ ์ด๋๋ฐ์ด์ ์ด๊ณ ์คํ๋ง ์ปจํ ์ด๋์ ์ง์ ๋ฑ๋กํ๊ฒ๋ ์ด๋๋ฐ์ด์ ์ด๋ค.
์ ๋ฆฌ
@Aspect๋ฅผ ์ฌ์ฉํด์ ์ ๋ ธํ ์ด์ ๊ธฐ๋ฐ ํ๋ก์๋ฅผ ๋งค์ฐ ํธ๋ฆฌํ๊ฒ ์ ์ฉํด๋ณด์๋ค.
์ค๋ฌด์์ ํ๋ก์๋ฅผ ์ ์ฉํ ๋๋ ๋๋ถ๋ถ ์ด ์ด ๋ฐฉ์์ ์ฌ์ฉํ๋ค.
์ง๊ธ๊น์ง ์ฐ๋ฆฌ๊ฐ ์งํํ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฐ์ ๋ก๊ทธ๋ฅผ ๋จ๊ธฐ๋ ๊ธฐ๋ฅ์ ํน์ ๊ธฐ๋ฅ ํ๋์ ๊ด์ฌ์ด ์๋ ๊ธฐ๋ฅ์ด ์๋๋ค.
์ ํ ๋ฆฌ์ผ์ด์
์ ์ฌ๋ฌ ๊ธฐ๋ฅ๋ค ์ฌ์ด์ ๊ฑธ์ณ์ ๋ค์ด๊ฐ๋ ๊ด์ฌ์ฌ์ด๋ค.
์ด๊ฒ์ ๋ฐ๋ก ํก๋จ ๊ด์ฌ์ฌ(cross-cutting concerns)๋ผ๊ณ ํ๋ค.
์ฐ๋ฆฌ๊ฐ ์ง๊ธ๊น์ง ์งํํ ๋ฐฉ๋ฒ์ด ์ด๋ ๊ฒ ์ฌ๋ฌ๊ณณ์ ๊ฑธ์ณ ์๋ ํก๋จ ๊ด์ฌ์ฌ์ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์ด์๋ค.
์ง๊ธ๊น์ง ํ๋ก์๋ฅผ ์ฌ์ฉํด์ ์ด๋ฌํ ํก๋จ ๊ด์ฌ์ฌ๋ฅผ ์ด๋ป๊ฒ ํด๊ฒฐํ๋์ง ์ ์ง์ ์ผ๋ก ๋งค์ฐ ๊น์ด์๊ฒ ํ์ตํ๊ณ ๊ธฐ๋ฐ์ ๋ค์ ธ ๋์๋ค. ์ด์ ์ด ๊ธฐ๋ฐ์ ๋ฐํ์ผ๋ก ์ด๋ฌํ ํก๋จ ๊ด์ฌ์ฌ๋ฅผ ์ ๋ฌธ์ผ๋ก ํด๊ฒฐํ๋ ์คํ๋ง AOP์ ๋ํด ๋ณธ๊ฒฉ์ ์ผ๋ก ์์๋ณด์.
'Spring > AOP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์คํ๋ง AOP ๊ตฌํ (0) | 2024.11.13 |
---|---|
์คํ๋ง AOP ๊ฐ๋ (0) | 2024.11.12 |
๋น ํ์ฒ๋ฆฌ๊ธฐ (0) | 2024.11.12 |
ํฌ์ธํธ์ปท, ์ด๋๋ฐ์ด์ค, ์ด๋๋ฐ์ด์ (0) | 2024.11.11 |
ํ๋ก์ ํฉํ ๋ฆฌ (0) | 2024.11.11 |