chapter 3. 스프링 aop
DESCRIPTION
Chapter 3. 스프링 AOP. 작성자 : 장은호 소속팀 : 네이버메인스포츠서비스개발팀 작성 일 : 2009/07/24. ⓒ 2009 NHN CORPORATION. 목차. 1. AOP. 1.1 AOP 용어 1.2 세 가지 Weaving 방식. 2. 스프링에서의 AOP. 2.1 프록시를 이용한 AOP 구현. 3. 스프링 API 를 이용한 AOP. 3.1 Advice 작성 3.2 Pointcut 및 Advisor 설정 - PowerPoint PPT PresentationTRANSCRIPT
Chapter 3. 스프링 AOP
작성자 : 장은호
소속팀 : 네이버메인스포츠서비스개발팀
작성일 : 2009/07/24
ⓒ 2009 NHN CORPORATION
목차
1. AOP1.1 AOP 용어
1.2 세 가지 Weaving 방식
2. 스프링에서의 AOP2.1 프록시를 이용한 AOP 구현
3. 스프링 API 를 이용한 AOP3.1 Advice 작성
3.2 Pointcut 및 Advisor 설정
3.3 ProxyFactoryBean 을 이용한 Advice 적용
3.4 DefaultAdvisorAutoProxyCreator 를 이용한 자동 프록시 생성
6. AspectJ 의 Pointcut 표현식
6.1 프록시 구현 방식에 따른 execution 적용 차이
4. POJO 클래스를 이용한 AOP4.1 XML 스키마를 이용한 AOP 설정
4.2 POJO 기반의 Advice 작성
4.3 스프링 API 를 이용한 Advice 설정
5. @Aspect 어노테이션을 이용한 AOP
1. AOP
1.0 Aspect?
1.1 AOP 용어
Advice- 언제 공통 관심 기능을 핵심 로직에 적용할지에 대한 정의 ( 예 : 메서드 호출 전에
시작한다 )
Joinpoint
- Advice 를 적용 가능한 지점 ( 예 : 메서드 호출지점 , 필드 )
Pointcut
- 실제 Advice 가 적용되는 지점 (Jointpoint 의 부분집합 )
Weaving- Advice 를 핵심 로직에 적용하는 것
Aspect
- 여러 객체에 공통으로 적용되는 공통 관심사항 ( 보안 , 로그 등 )
Advisor
- Advice + Pointcut
proxy-bean
1.2 세 가지 Weaving 방식
컴파일 시에 Weaving 하기: 핵심 로직 부분을 컴파일할 때 , 컴파일러가 공통코드를 삽입 = AOP 가 적용된 클래스
파일 생성
클래스 로딩 시에 Weaving 하기: JVM 레벨에서 바이트코드 조작
런타임 시에 Weaving 하기: 조작 없이 순수한 자바언어 +API ( 프록시 기반 ) = 스프링에서 사용하는 방식
2. 스프링에서의 AOP
2.1 프록시를 이용한 AOP 구현
스프링 API 를 이용한 AOP 구현 : Ch. 3.3
POJO 클래스를 이용한 AOP 구현 : Ch. 3.4
AspectJ 5 에서 정의한 @Aspect 어노테이션 기반의 AOP 구현 : Ch. 3.5
스프링 내부에서의 처리는 같으므로 메서드 호출에 대한 AOP 만 구현됨
3. 스프링 API 를 이용한 AOP
3.1 Advice 작성
MethodBeforeAdvice : 대상 객체의 메서드 실행 전
AfterReturningAdvice : 대상 객체의 메서드 실행 후
public class AfterReturningLogAdvice implements AfterReturningAdvice {private Log log = LogFactory.getLog(getClass());@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws
Throwable {if (log.isTraceEnabled())
log.trace(method.getName() + " on " + target + " called, return value is " + returnValue);}
}
public class MethodBeforeLogAdvice implements MethodBeforeAdvice {private Log log = LogFactory.getLog(getClass());@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {
if (log.isTraceEnabled()) log.trace(method.toString());
}}
ThrowsAdvice : 대상 객체의 메서드에서 예외가 발생했을 때
void afterThrowing([Method method, Object[] args, Object target], ExceptionType)
3.1 Advice 작성
MethodInterceptor : All in onepublic class MethodInterceptorLogAdvice implements MethodInterceptor {
private Log log = LogFactory.getLog(getClass());
@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {if (log.isTraceEnabled())
log.trace(invocation.getMethod().getName() + "calling");
try {Object returnValue = invocation.proceed();if (log.isTraceEnabled())
log.trace(invocation.getMethod().getName() + " called, return value is " + return-Value);
} catch (Throwable e) {if (log.isTraceEnabled())
log.error(invocation.getMethod().getName());throw e;
} finally {if (log.isTraceEnabled())
log.trace(invocation.getMethod().getName() + "completed.");}
}
3.2 Pointcut 및 Advisor 설정
JdkRegexpMethodPointCut(Perl5RegexpMethodPointcut)<bean id="writePointcut"
class="org.springframework.aop.support.JdkRegexpMethodPointCut"><property name="pattern" value=".*write.*" />
</bean>
<bead id="readPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointCut"><property name="paterns">
<list><value>.*readArticle.*</value><value>.*readComment.*</value>
</list></property>
</bean>
<bean id="beforeLogAdvice" class="MethodBeforeLogAdvice" />
<bean id="writeAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"><property name="advice" ref="beforeLogAdvice" /><property name="pointcut" ref="writePointcut" />
</bean>
3.2 Pointcut 및 Advisor 설정
AspectJExpressionPointcut<bean id=“getPointcut"
class="org.springframework.aop.aspectj.AspectJExpressionPointcut"><property name=“expression" value=“execution(public !void get*(..))” />
</bean>
<bean id=“getAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"><property name="advice" ref=“cacheAdvice" /><property name="pointcut" ref=“getPointcut" />
</bean>
3.3 ProxyFactoryBean 을 이용한 Advice 적용
ProxyFactoryBean : AOP 를 적용할 객체에 프록시를 적용시켜 줌
<bean id="writeArticleServiceTarget" class=“...WriteArticleServiceImpl" />
<bean id="writeAdvisor" class="...RegexpMethodPointcutAdvisor">...
</bean>
<bean id="writeArticleService" class="org.springframework.aop.framework.ProxyFactoryBean"><property name="target" ref="writeArticleServiceTarget" /><property name="interceptorNames">
<list><value>writeAdvisor</value><value>afterLogAdvice</value>
</list></property><property name=“proxyInterfaces”>
<list><value>WriteArticleService</value>
</list></property>
</bean>
3.3 ProxyFactoryBean 을 이용한 Advice 적용
ProxyFactoryBean : AOP 를 적용할 객체에 프록시를 적용시켜 줌
String[] configs = {“contextApi.xml”};ApplicationContext context = new ClassPathXmlApplicationContext(configs);ReadArticleService readArticleService1 = (ReadArticleService) context.getBean(“readArticleService”); // It’s Proxy-
beanReadArticleService readArticleService2 = (ReadArticleService) context.getBean(“readArticleServiceTarget”); // Just bean
3.4 DefaultAdvisorAutoProxyCreator 를 이용한 자동 프록시 생성
<bean class=“org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator” />
<bead id=“writeArticleService” class=“…” />
<bean id=“beforeLogAdvice” class=…” />
<bean id=“beforeLogAdvisor” class=“org.springframwrodk.aop.aspectj.AspectJExpressionPointcutAdvisor”><property name=“advice” ref=“beforeLogAdvice” /><property name=“expression” value=:execution(public * *(..))” />
</bean>
ProxyFactoryBean 클래스를 사용하지 않아도 자동으로 Advisor 적용
4. POJO 클래스를 이용한 AOP
4.1 XML 스키마를 이용한 AOP 설정
AOP 설정 정보임을 나타내는 태그 : <aop:config>Aspect 설정 : <aop:aspect>
Pointcut 설정 : <aop:pointcut>Advice 설정 : <aop:around>
메서드 실행 전 : <aop:before>메서드가 정상적으로 실행된 후 : <aop:after-returning>메서드가 예외를 발생시킬 때 : <aop:atfer-throwing>메서드가 ( 예외 발생에 상관없이 ) 종료된 경우 : <aop:after>모든 시점에 적용 가능 : <aop:around>
<bean id="logging" class="LoggingAspect" />
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:pointcut id="publicMethod" expression="execution(public * (..))" />
<aop:around pointcut-ref="publicMethod" method="logging" /></aop:aspect>
</aop:config>
<bean id="readArticleService" class="ReadArticleServiceImpl" />
</beans>
4.2 POJO 기반의 Advice 작성
1) Before Advice
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:before pointcut-ref="publicMethod" method=“beforeLogging" /></aop:aspect>
</aop:config>2) After Returning Advice
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:after-returning pointcut-ref="publicMethod" method=“returninigLogging" returning=“ret” /></aop:aspect>
</aop:config>3) After Throwing Advice
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:after-throwing pointcut-ref="publicMethod" method=“throwingLogging" throwing=“ex” /></aop:aspect>
</aop:config>
4.2 POJO 기반의 Advice 작성
4) After Advice
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:after pointcut-ref="publicMethod" method=“afterLogging" /></aop:aspect>
</aop:config>5) Around Advice
<aop:config><aop:aspect id="loggingAspect" ref="logging">
<aop:around pointcut-ref="publicMethod" method=“returninigLogging“ /></aop:aspect>
</aop:config>
4.3 스프링 API 를 이용한 Advice 설정
<bead id="afterReturnAdvice" class="AfterReturningLogAdvice" />
<aop:config><aop:pointcut id="publicMethod" expression="execution(public *(..))" /><aop:advisor advice-ref="afterReturnAdvice" pointcut-ref="publicMethod" />
</aop:config>
5. @Aspect 어노테이션을 이용한 AOP
5.1 @Aspect Annotaion
// 설정 파일에 : <aop:aspectj=autoproxy />
// 적용할 Aspect 안에
@Aspectpublic class AnnoLoggingAspect {
private Log log = LogFactory.getLog(getClass());
// Advice 와 Pointcut 을 기술
@Before("execution(public * *(..))")public String beforeLogging(JoinPoint joinPoint) {
String methodName = joinPoint.getSignature().getName();if (log.isTraceEnabled())
log.trace("calling: " + methodName);return methodName;
}}
Thank you.