๐ก ๊น์ํ๋์ ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์ ๋๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ
@Bean์ด๋ ์ปดํฌ๋ํธ ์ค์บ์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ฉด, ์คํ๋ง์ ๋์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ณ ์คํ๋ง ์ปจํ ์ด๋ ๋ด๋ถ์ ๋น ์ ์ฅ์์ ๋ฑ๋กํ๋ค. ๊ทธ๋ฆฌ๊ณ ์ดํ์๋ ์คํ๋ง ์ปจํ ์ด๋๋ฅผ ํตํด ๋ฑ๋กํ ์คํ๋ง ๋น์ ์กฐํํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ - BeanPostProcessor
์คํ๋ง์ด ๋น ์ ์ฅ์์ ๋ฑ๋กํ ๋ชฉ์ ์ผ๋ก ์์ฑํ ๊ฐ์ฒด๋ฅผ ๋น ์ ์ฅ์์ ๋ฑ๋กํ๊ธฐ ์ง์ ์ ์กฐ์ํ๊ณ ์ถ๋ค๋ฉด ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ ๊ณผ์
- ์์ฑ: ์คํ๋ง ๋น ๋์์ด ๋๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. ( @Bean, ์ปดํฌ๋ํธ ์ค์บ ๋ชจ๋ ํฌํจ)
- ์ ๋ฌ: ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ๋น ์ ์ฅ์์ ๋ฑ๋กํ๊ธฐ ์ง์ ์ ๋น ํ์ฒ๋ฆฌ๊ธฐ์ ์ ๋ฌํ๋ค.
- ํ ์ฒ๋ฆฌ ์์ : ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์ ๋ฌ๋ ์คํ๋ง ๋น ๊ฐ์ฒด๋ฅผ ์กฐ์ํ๊ฑฐ๋ ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ฐ๋์น๊ธฐ ํ ์ ์๋ค.
- ๋ฑ๋ก: ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ๋น์ ๋ฐํํ๋ค. ์ ๋ฌ ๋ ๋น์ ๊ทธ๋๋ก ๋ฐํํ๋ฉด ํด๋น ๋น์ด ๋ฑ๋ก๋๊ณ , ๋ฐ๊ฟ์น๊ธฐ ํ๋ฉด ๋ค๋ฅธ ๊ฐ์ฒด๊ฐ ๋น ์ ์ฅ์์ ๋ฑ๋ก๋๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ๋น์ ์กฐ์ํ๊ณ ๋ณ๊ฒฝํ ์ ์๋ ํํน ํฌ์ธํธ์ด๋ค.
์ด๊ฒ์ ๋น ๊ฐ์ฒด๋ฅผ ์กฐ์ํ๊ฑฐ๋ ์ฌ์ง์ด ๋ค๋ฅธ ๊ฐ์ฒด๋ก ๋ฐ๊พธ์ด ๋ฒ๋ฆด ์ ์์ ์ ๋๋ก ๋ง๊ฐํ๋ค.
์ฌ๊ธฐ์ ์กฐ์์ด๋ผ๋ ๊ฒ์ ํด๋น ๊ฐ์ฒด์ ํน์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ ๋ปํ๋ค.
์ผ๋ฐ์ ์ผ๋ก ์คํ๋ง ์ปจํ
์ด๋๊ฐ ๋ฑ๋กํ๋, ํนํ ์ปดํฌ๋ํธ ์ค์บ์ ๋์์ด ๋๋ ๋น๋ค์ ์ค๊ฐ์ ์กฐ์ํ ๋ฐฉ๋ฒ์ด ์๋๋ฐ, ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ฐ๋ฐ์๊ฐ ๋ฑ๋กํ๋ ๋ชจ๋ ๋น์ ์ค๊ฐ์ ์กฐ์ํ ์ ์๋ค. ์ด ๋ง์ ๋น ๊ฐ์ฒด๋ฅผ ํ๋ก์๋ก ๊ต์ฒดํ๋ ๊ฒ๋ ๊ฐ๋ฅํ๋ค๋ ๋ป์ด๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ ์ ์ฉํ๊ธฐ
๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํด์ ์ค์ ๊ฐ์ฒด ๋์ ํ๋ก์๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํด๋ณด์.
์ด๋ ๊ฒ ํ๋ฉด ์๋์ผ๋ก ๋ฑ๋กํ๋ ๋น์ ๋ฌผ๋ก ์ด๊ณ , ์ปดํฌ๋ํธ ์ค์บ์ ์ฌ์ฉํ๋ ๋น๊น์ง ๋ชจ๋ ํ๋ก์๋ฅผ ์ ์ฉํ ์ ์๋ค. ์ปดํฌ๋ํธ ์ค์บ ๊ฐ์ ๊ฒฝ์ฐ์๋ ์คํ๋ง์ด ์๋์ผ๋ก ์ปจํ
์ด๋์ ๋น์ ๋ฑ๋กํด์ ์ฐ๋ฆฌ๊ฐ ํ๋ก์๋ฅผ ์ ์ฉํ ๋ฐฉ๋ฒ์ด ์์๋๋ฐ ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์คํ๋ง์ด ์ปจํ
์ด๋์ ์ค์ ๊ฐ์ฒด ๋น์ ์ ์ฅํ๊ธฐ ์ ์ ํ๋ก์ ๊ฐ์ฒด๋ก ๋ฐ๊ฟ์น๊ธฐ๊ฐ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์ด๋ค. ๋ ๋์๊ฐ์ ์ค์ ํ์ผ์ ์๋ ์ ๋ง์ ํ๋ก์ ์์ฑ ์ฝ๋๋ ํ๋ฒ์ ์ ๊ฑฐํ ์ ์๋ค.
PackageLogTracePostProcessor
@Slf4j
public class PackageLogTracePostProcessor implements BeanPostProcessor {
private final String basePackage;
private final Advisor advisor;
public PackageLogTracePostProcessor(String basePackage, Advisor advisor) {
this.basePackage = basePackage;
this.advisor = advisor;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
log.info("param beanName={} bean={}", beanName, bean.getClass());
//ํ๋ก์ ์ ์ฉ ๋์ ์ฌ๋ถ ์ฒดํฌ
//ํ๋ก์ ์ ์ฉ ๋์์ด ์๋๋ฉด ์๋ณธ์ ๊ทธ๋๋ก ์งํ
String packageName = bean.getClass().getPackageName();
if (!packageName.startsWith(basePackage)) {
return bean;
}
//ํ๋ก์ ๋์์ด๋ฉด ํ๋ก์๋ฅผ ๋ง๋ค์ด์ ๋ฐํ
ProxyFactory proxyFactory = new ProxyFactory(bean);
proxyFactory.addAdvisor(advisor);
Object proxy = proxyFactory.getProxy();
log.info("create proxy: target={} proxy={}", bean.getClass(), proxy.getClass());
return proxy;
}
}
- PackageLogTraceProxyPostProcessor๋ ์๋ณธ ๊ฐ์ฒด๋ฅผ ํ๋ก์ ๊ฐ์ฒด๋ก ๋ณํํ๋ ์ญํ ์ ํ๋ค. ์ด๋ ํ๋ก์ ํฉํ ๋ฆฌ๋ฅผ ์ฌ์ฉํ๋๋ฐ, ํ๋ก์ ํฉํ ๋ฆฌ๋ advisor๊ฐ ํ์ํ๊ธฐ ๋๋ฌธ์ ์ด ๋ถ๋ถ์ ์ธ๋ถ์์ ์ฃผ์ ๋ฐ๋๋ก ํ๋ค.
- ํ๋ก์ ์ ์ฉ ๋์์ ๋ฐํ ๊ฐ์ ๋ณด๋ฉด ์๋ณธ ๊ฐ์ฒด ๋์ ์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ๋ฐํํ๋ค. ๋ฐ๋ผ์ ์คํ๋ง ์ปจํ ์ด๋์ ์๋ณธ ๊ฐ์ฒด ๋์ ์ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋๋ค. ์๋ณธ ๊ฐ์ฒด๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋์ง ์๋๋ค.
BeanPostProcessorConfig
@Slf4j
@Configuration
@Import({AppV1Config.class, AppV2Config.class})
public class BeanPostProcessorConfig {
@Bean
public PackageLogTracePostProcessor logTracePostProcessor(LogTrace logTrace) {
return new PackageLogTracePostProcessor("hello.proxy.app", getAdvisor(logTrace));
}
private Advisor getAdvisor(LogTrace logTrace) {
//pointcut
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.setMappedNames("request*", "order*", "save*");
//advice
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice);
}
}
@Bean
logTraceProxyPostProcessor()
ํน์ ํจํค์ง๋ฅผ ๊ธฐ์ค์ผ๋ก ํ๋ก์๋ฅผ ์์ฑํ๋ ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.
๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์คํ๋ง ๋น์ผ๋ก๋ง ๋ฑ๋กํ๋ฉด ์๋์ผ๋ก ๋์ํ๋ค.
์ฌ๊ธฐ์ ํ๋ก์๋ฅผ ์ ์ฉํ ํจํค์ง ์ ๋ณด( hello.proxy.app )์ ์ด๋๋ฐ์ด์ ( getAdvisor(logTrace) )๋ฅผ ๋๊ฒจ์ค๋ค.
์ด์ ํ๋ก์๋ฅผ ์์ฑํ๋ ์ฝ๋๊ฐ ์ค์ ํ์ผ์๋ ํ์ ์๋ค.
์์ํ ๋น ๋ฑ๋ก๋ง ๊ณ ๋ฏผํ๋ฉด ๋๋ค.
ํ๋ก์๋ฅผ ์์ฑํ๊ณ ํ๋ก์๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ ๊ฒ์ ๋น ํ์ฒ๋ฆฌ๊ธฐ๊ฐ ๋ชจ๋ ์ฒ๋ฆฌํด์ค๋ค.
์คํ๋ง์ด ์ ๊ณตํ๋ ๋น ํ์ฒ๋ฆฌ๊ธฐ
build.gradle - ์ถ๊ฐ
implementation 'org.springframework.boot:spring-boot-starter-aop'
์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ถ๊ฐํ๋ฉด aspectjweaver๋ผ๋ aspectJ ๊ด๋ จ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ฑ๋กํ๊ณ , ์คํ๋ง ๋ถํธ๊ฐ AOP ๊ด๋ จ ํด๋์ค๋ฅผ ์๋์ผ๋ก ์คํ๋ง ๋น์ ๋ฑ๋กํ๋ค.
์๋ ํ๋ก์ ์์ฑ๊ธฐ - AutoProxyCreator
- ์์ ์ด์ผ๊ธฐํ ์คํ๋ง ๋ถํธ ์๋ ์ค์ ์ผ๋ก AnnotationAwareAspectJAutoProxyCreator๋ผ๋ ๋น ํ์ฒ๋ฆฌ๊ธฐ๊ฐ ์คํ๋ง ๋น์ ์๋์ผ๋ก ๋ฑ๋ก๋๋ค. ์ด๋ฆ ๊ทธ๋๋ก ์๋์ผ๋ก ํ๋ก์๋ฅผ ์์ฑํด์ฃผ๋ ๋น ํ์ฒ๋ฆฌ๊ธฐ์ด๋ค.
- ์ด ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋ Advisor ๋ค์ ์๋์ผ๋ก ์ฐพ์์ ํ๋ก์๊ฐ ํ์ํ ๊ณณ์ ์๋์ผ๋ก ํ๋ก์๋ฅผ ์ ์ฉํด์ค๋ค.
- Advisor ์์๋ Pointcut๊ณผ Advice๊ฐ ์ด๋ฏธ ๋ชจ๋ ํฌํจ๋์ด ์๋ค. ๋ฐ๋ผ์ Advisor๋ง ์๊ณ ์์ผ๋ฉด ๊ทธ ์์ ์๋ Pointcut์ผ๋ก ์ด๋ค ์คํ๋ง ๋น์ ํ๋ก์๋ฅผ ์ ์ฉํด์ผ ํ ์ง ์ ์ ์๋ค. ๊ทธ๋ฆฌ๊ณ Advice๋ก ๋ถ๊ฐ ๊ธฐ๋ฅ์ ์ ์ฉํ๋ฉด ๋๋ค.
์๋ ํ๋ก์ ์์ฑ๊ธฐ์ ์๋ ๊ณผ์ ์ ์์๋ณด์
- ์์ฑ: ์คํ๋ง์ด ์คํ๋ง ๋น ๋์์ด ๋๋ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ค. (@Bean , ์ปดํฌ๋ํธ ์ค์บ ๋ชจ๋ ํฌํจ)
- ์ ๋ฌ: ์์ฑ๋ ๊ฐ์ฒด๋ฅผ ๋น ์ ์ฅ์์ ๋ฑ๋กํ๊ธฐ ์ง์ ์ ๋น ํ์ฒ๋ฆฌ๊ธฐ์ ์ ๋ฌํ๋ค.
- ๋ชจ๋ Advisor ๋น ์กฐํ: ์๋ ํ๋ก์ ์์ฑ๊ธฐ - ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์คํ๋ง ์ปจํ ์ด๋์์ ๋ชจ๋ Advisor๋ฅผ ์กฐํํ๋ค.
- ํ๋ก์ ์ ์ฉ ๋์ ์ฒดํฌ: ์์ ์กฐํํ Advisor์ ํฌํจ๋์ด ์๋ ํฌ์ธํธ์ปท์ ์ฌ์ฉํด์ ํด๋น ๊ฐ์ฒด๊ฐ ํ๋ก์๋ฅผ ์ ์ฉํ ๋์์ธ์ง ์๋์ง ํ๋จํ๋ค. ์ด๋ ๊ฐ์ฒด์ ํด๋์ค ์ ๋ณด๋ ๋ฌผ๋ก ์ด๊ณ , ํด๋น ๊ฐ์ฒด์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ํฌ์ธํธ์ปท์ ํ๋ํ๋ ๋ชจ๋ ๋งค์นญํด๋ณธ๋ค. ๊ทธ๋์ ์กฐ๊ฑด์ด ํ๋๋ผ๋ ๋ง์กฑํ๋ฉด ํ๋ก์ ์ ์ฉ ๋์์ด ๋๋ค. ์๋ฅผ ๋ค์ด์ 10๊ฐ์ ๋ฉ์ ๋ ์ค์ ํ๋๋ง ํฌ์ธํธ์ปท ์กฐ๊ฑด์ ๋ง์กฑํด๋ ํ๋ก์ ์ ์ฉ ๋์์ด ๋๋ค.
- ํ๋ก์ ์์ฑ: ํ๋ก์ ์ ์ฉ ๋์์ด๋ฉด ํ๋ก์๋ฅผ ์์ฑํ๊ณ ๋ฐํํด์ ํ๋ก์๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค. ๋ง์ฝ ํ๋ก์ ์ ์ฉ ๋์์ด ์๋๋ผ๋ฉด ์๋ณธ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ ์๋ณธ ๊ฐ์ฒด๋ฅผ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ค.
- ๋น ๋ฑ๋ก: ๋ฐํ๋ ๊ฐ์ฒด๋ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋๋ค.
์์ฑ๋ ํ๋ก์
ํ๋ก์๋ ๋ด๋ถ์ ์ด๋๋ฐ์ด์ ์ ์ค์ ํธ์ถํด์ผํ ๋์ ๊ฐ์ฒด( target )์ ์๊ณ ์๋ค.
์ฝ๋๋ฅผ ํตํด ๋ฐ๋ก ์ ์ฉํด๋ณด์.
์ฝ๋ ์์
@Configuration
@Import({AppV1Config.class, AppV2Config.class})
public class AutoProxyConfig {
@Bean
public Advisor advisor1(LogTrace logTrace) {
//pointcut
NameMatchMethodPointcut pointcut = new NameMatchMethodPointcut();
pointcut.setMappedNames("request*", "order*", "save*");
//advice
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice);
}
}
- AutoProxyConfig ์ฝ๋๋ฅผ ๋ณด๋ฉด advisor1์ด๋ผ๋ ์ด๋๋ฐ์ด์ ํ๋๋ง ๋ฑ๋กํ๋ค.
- ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ ์ด์ ๋ฑ๋กํ์ง ์์๋ ๋๋ค. ์คํ๋ง์ ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ผ๋(AnnotationAwareAspectJAutoProxyCreator) ๋น ํ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์๋์ผ๋ก ๋ฑ๋กํด์ค๋ค.
- ์ด ํ๋ก์ ์์ฑ๊ธฐ๊ฐ ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋ก๋ Advisor๋ค์ ๋ชจ๋ ์กฐํํด์ Advisor์ ํฌํจ๋์ด ์๋ ํฌ์ธํธ์ปท์ ์ฌ์ฉํด์ ํด๋น ๊ฐ์ฒด๊ฐ ํ๋ก์๋ฅผ ์ ์ฉํ ๋์์ธ์ง ์๋์ง ํ๋จํ๋ค.
@Import(AutoProxyConfig.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();
}
}
ํฌ์ธํธ์ปท์ 2๊ฐ์ง์ ์ฌ์ฉ๋๋ค.
1. ํ๋ก์ ์ ์ฉ ์ฌ๋ถ ํ๋จ - ์์ฑ ๋จ๊ณ
์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ ํฌ์ธํธ์ปท์ ์ฌ์ฉํด์ ํด๋น ๋น์ด ํ๋ก์๋ฅผ ์์ฑํ ํ์๊ฐ ์๋์ง ์๋์ง ์ฒดํฌํ๋ค.
ํด๋์ค + ๋ฉ์๋ ์กฐ๊ฑด์ ๋ชจ๋ ๋น๊ตํ๋ค.
์ด๋ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์ฒดํฌํ๋๋ฐ, ํฌ์ธํธ์ปท ์กฐ๊ฑด์ ํ๋ํ๋ ๋งค์นญํด ๋ณธ๋ค.
๋ง์ฝ ์กฐ๊ฑด์ ๋ง๋ ๊ฒ์ด ํ๋๋ผ๋ ์์ผ๋ฉด ํ๋ก์๋ฅผ ์์ฑํ๋ค.
์์
- orderControllerV1์ request(), noLog()๊ฐ ์๋ค.
- ์ฌ๊ธฐ์์ request()๊ฐ ์กฐ๊ฑด์ ๋ง์กฑํ๋ฏ๋ก ํ๋ก์๋ฅผ ์์ฑํ๋ค.
- ๋ง์ฝ ์กฐ๊ฑด์ ๋ง๋ ๊ฒ์ด ํ๋๋ ์์ผ๋ฉด ํ๋ก์๋ฅผ ์์ฑํ ํ์๊ฐ ์์ผ๋ฏ๋ก ํ๋ก์๋ฅผ ์์ฑํ์ง ์๋๋ค.
2. ์ด๋๋ฐ์ด์ค ์ ์ฉ ์ฌ๋ถ ํ๋จ - ์ฌ์ฉ ๋จ๊ณ
ํ๋ก์๊ฐ ํธ์ถ๋์์ ๋ ๋ถ๊ฐ ๊ธฐ๋ฅ์ธ ์ด๋๋ฐ์ด์ค๋ฅผ ์ ์ฉํ ์ง ๋ง์ง ํฌ์ธํธ์ปท์ ๋ณด๊ณ ํ๋จํ๋ค.
์์ ์ค๋ช ํ ์์์ orderControllerV1์ ์ด๋ฏธ ํ๋ก์๊ฐ ๊ฑธ๋ ค์๋ค.
orderControllerV1์ request()๋ ํ์ฌ ํฌ์ธํธ์ปท ์กฐ๊ฑด์ ๋ง์กฑํ๋ฏ๋ก ํ๋ก์๋ ์ด๋๋ฐ์ด์ค๋ฅผ ๋จผ์ ํธ์ถํ๊ณ , target์ ํธ์ถํ๋ค. orderControllerV1์ noLog()๋ ํ์ฌ ํฌ์ธํธ์ปท ์กฐ๊ฑด์ ๋ง์กฑํ์ง ์์ผ๋ฏ๋ก ์ด๋๋ฐ์ด์ค๋ฅผ ํธ์ถํ์ง ์๊ณ ๋ฐ๋ก target๋ง ํธ์ถํ๋ค.
์ฐธ๊ณ
ํ๋ก์๋ฅผ ๋ชจ๋ ๊ณณ์ ์์ฑํ๋ ๊ฒ์ ๋น์ฉ ๋ญ๋น์ด๋ค.
๊ผญ ํ์ํ ๊ณณ์ ์ต์ํ์ ํ๋ก์๋ฅผ ์ ์ฉํด์ผ ํ๋ค. ๊ทธ๋์ ์๋ ํ๋ก์ ์์ฑ๊ธฐ๋ ๋ชจ๋ ์คํ๋ง ๋น์ ํ๋ก์๋ฅผ ์ ์ฉํ๋ ๊ฒ์ด ์๋๋ผ ํฌ์ธํธ์ปท์ผ๋ก ํ๋ฒ ํํฐ๋งํด์ ์ด๋๋ฐ์ด์ค๊ฐ ์ฌ์ฉ๋ ๊ฐ๋ฅ์ฑ์ด ์๋ ๊ณณ์๋ง ํ๋ก์๋ฅผ ์์ฑํ๋ค.
ํฌ์ธํธ์ปท ์ ์ฉํ๊ธฐ
๋จ์ํ ๋ฉ์๋ ์ด๋ฆ์ `"request*", "order*", "save*"๋ง ํฌํจ๋์ด ์์ผ๋ฉด ํฌ์ธํธ์ปท์ด ๋งค์นญ ๋๋ค๊ณ ํ๋จ๋๋ค. ๋ฐ๋ผ์ ์คํ๋ง์ด ๋ด๋ถ์์ ์ฌ์ฉํ๋ ๋น์๋ ๋ฉ์๋ ์ด๋ฆ์ request๋ผ๋ ๋จ์ด๋ง ๋ค์ด๊ฐ ์์ผ๋ฉด ํ๋ก์๊ฐ ๋ง๋ค์ด์ง๊ณ ๋๊ณ , ์ด๋๋ฐ์ด์ค๋ ์ ์ฉ๋๋ ๊ฒ์ด๋ค. ๊ทธ๋ฌ๋ฏ๋ก ํจํค์ง์ ๋ฉ์๋ ์ด๋ฆ๊น์ง ํจ๊ป ์ง์ ํ ์ ์๋ ๋งค์ฐ ์ ๋ฐํ ํฌ์ธํธ์ปท์ด ํ์ํ๋ค.
AspectJExpressionPointcut
AspectJ๋ผ๋ AOP์ ํนํ๋ ํฌ์ธํธ์ปท ํํ์์ ์ ์ฉํ ์ ์๋ค.
advisor2
@Bean
public Advisor advisor2(LogTrace logTrace) {
//pointcut
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* hello.proxy.app..*(..))");
//advice
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice);
}
- AspectJExpressionPointcut: AspectJ ํฌ์ธํธ์ปท ํํ์์ ์ ์ฉํ ์ ์๋ค.
- execution(* hello.proxy.app..*(..)): AspectJ๊ฐ ์ ๊ณตํ๋ ํฌ์ธํธ์ปท ํํ์์ด๋ค.
- *: ๋ชจ๋ ๋ฐํ ํ์
- hello.proxy.app..: ํด๋น ํจํค์ง์ ๊ทธ ํ์ ํจํค์ง
- *(..): * ๋ชจ๋ ๋ฉ์๋ ์ด๋ฆ, (..) ํ๋ผ๋ฏธํฐ๋ ์๊ด ์์
์ ๊ฒฝ์ฐ๋ hello.proxy.app ํจํค์ง์ ๊ทธ ํ์ ํจํค์ง์ ๋ชจ๋ ๋ฉ์๋๋ ํฌ์ธํธ์ปท์ ๋งค์นญ ๋์์ด ๋๋ค.
advisor3
@Bean
public Advisor advisor3(LogTrace logTrace) {
//pointcut
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* hello.proxy.app..*(..)) && !execution(* hello.proxy.app..noLog(..))");
//advice
LogTraceAdvice advice = new LogTraceAdvice(logTrace);
return new DefaultPointcutAdvisor(pointcut, advice);
}
ํํ์์ ๋ค์๊ณผ ๊ฐ์ด ์์ ํ๋ค.
execution(* hello.proxy.app..*(..)) && !execution(* hello.proxy.app..noLog(..))
- && : ๋ ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํด์ผ ํจ
- ! : ๋ฐ๋
hello.proxy.app ํจํค์ง์ ํ์ ํจํค์ง์ ๋ชจ๋ ๋ฉ์๋๋ ํฌ์ธํธ์ปท์ ๋งค์นญํ๋, noLog() ๋ฉ์๋๋ ์ ์ธํ๋ผ๋ ๋ป์ด๋ค.
ํ๋์ ํ๋ก์, ์ฌ๋ฌ Advisor ์ ์ฉ
์๋ฅผ ๋ค์ด์ ์ด๋ค ์คํ๋ง ๋น์ด advisor1, advisor2๊ฐ ์ ๊ณตํ๋ ํฌ์ธํธ์ปท์ ์กฐ๊ฑด์ ๋ชจ๋ ๋ง์กฑํ๋ฉด ํ๋ก์ ์๋ ์์ฑ๊ธฐ๋ ํ๋ก์๋ฅผ ๋ช๊ฐ ์์ฑํ ๊น? ํ๋ก์ ์๋ ์์ฑ๊ธฐ๋ ํ๋ก์๋ฅผ ํ๋๋ง ์์ฑํ๋ค. ์๋ํ๋ฉด ํ๋ก์ ํฉํ ๋ฆฌ๊ฐ ์์ฑํ๋ ํ๋ก์๋ ๋ด๋ถ์ ์ฌ๋ฌ advisor๋ค์ ํฌํจํ ์ ์๊ธฐ ๋๋ฌธ์ด๋ค. ๋ฐ๋ผ์ ํ๋ก์๋ฅผ ์ฌ๋ฌ๊ฐ ์์ฑํด์ ๋น์ฉ์ ๋ญ๋นํ ์ด์ ๊ฐ ์๋ค.
ํ๋ก์ ์๋ ์์ฑ๊ธฐ ์ํฉ๋ณ ์ ๋ฆฌ
- advisor1์ ํฌ์ธํธ์ปท๋ง ๋ง์กฑ ํ๋ก์ 1๊ฐ ์์ฑ, ํ๋ก์์ advisor1๋ง ํฌํจ
- advisor1, advisor2์ ํฌ์ธํธ์ปท์ ๋ชจ๋ ๋ง์กฑ ํ๋ก์1๊ฐ ์์ฑ, ํ๋ก์์ advisor1, advisor2 ๋ชจ๋ ํฌํจ
- advisor1, advisor2์ ํฌ์ธํธ์ปท์ ๋ชจ๋ ๋ง์กฑํ์ง ์์ ํ๋ก์๊ฐ ์์ฑ๋์ง ์์
์คํ ํ๋ฆ
์๋ ํ๋ก์ ์์ฑ๊ธฐ์ธ AnnotationAwareAspectJAutoProxyCreator๋๋ถ์ ๊ฐ๋ฐ์๋ ๋งค์ฐ ํธ๋ฆฌํ๊ฒ ํ๋ก์ ๋ฅผ ์ ์ฉํ ์ ์๋ค. ์ด์ Advisor๋ง ์คํ๋ง ๋น์ผ๋ก ๋ฑ๋กํ๋ฉด ๋๋ค.
Advisor = Pointcut + Advice
'Spring > AOP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์คํ๋ง AOP ๊ฐ๋ (0) | 2024.11.12 |
---|---|
@Aspect AOP (0) | 2024.11.12 |
ํฌ์ธํธ์ปท, ์ด๋๋ฐ์ด์ค, ์ด๋๋ฐ์ด์ (0) | 2024.11.11 |
ํ๋ก์ ํฉํ ๋ฆฌ (0) | 2024.11.11 |
CGLIB (0) | 2024.11.11 |