- 다음과 같은 인터페이스와 타겟 클레스가 있다.
package
onj.aop.aspectjannotation;
interface OnjWorld
{
public
void onjHello();
public
void onjHello2() throws Exception;
}
package
onj.aop.aspectjannotation;
//Target
Class
public class OnjWorldImpl
implements OnjWorld {
public
void onjHello() {
System.out.println("OnJ에오신것을
환영합니다.");
}
public
void onjHello2() throws Exception {
System.out.println("OnJ2에오신것을
환영합니다.");
throw
new Exception("OnJ Exception...");
}
}
위 OnjWorldImpl이 타겟 클래스이다. onjHello2 로 시작하는 메소드에 스프링 충고를 내릴려고 한다.
충고(Advice)는 적당히 콘솔화면에 출력하는 정도로 만들고...
before advice, around advice, throws advice, after,after returning advice를 구현하시오.
- @AspectJ Annotation을 이용하여 구현해 보았다.
가장
핵심이 되는 클래스는 Aspect인 AonjLoggingAspect이다. 그안에 충고, 포인트컷에 대한 AspectJ 표현식등이 기술되어
Aspect(Advice + PointCut)를 만든다.
1. OnjWorld.java
package
onj.aop.aspectjannotation;
interface OnjWorld
{
public
void onjHello();
public
void onjHello2() throws Exception;
}
2.
OnjWorldImpl.java
package onj.aop.aspectjannotation;
public class OnjWorldImpl implements OnjWorld {
public void
onjHello() {
System.out.println("OnJ에오신것을
환영합니다.");
}
public void
onjHello2() throws Exception {
System.out.println("OnJ2에오신것을
환영합니다.");
throw new
Exception("OnJ Exception...");
}
}
3.
OnjLoggingAspect.java
package
onj.aop.aspectjannotation;
import
java.util.Arrays;
import
org.aspectj.lang.JoinPoint;
import
org.aspectj.lang.ProceedingJoinPoint;
import
org.aspectj.lang.annotation.After;
import
org.aspectj.lang.annotation.AfterReturning;
import
org.aspectj.lang.annotation.AfterThrowing;
import
org.aspectj.lang.annotation.Around;
import
org.aspectj.lang.annotation.Aspect;
import
org.aspectj.lang.annotation.Before;
@Aspect
public class
OnjLoggingAspect {
//사전충고(Before
Advice)
@Before("execution (*
onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
public void
logBefore(JoinPoint joinPoint){
System.out.println("<<<<<
Advice-->logBefore()...");
joinPoint.getSignature().getName();
}
//사후중고(After Advice),
타겟메소드 실행 후 즉시 실행
@After("execution (*
onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
public void
logAfter(JoinPoint joinPoint){
System.out.println("<<<<< Advice -->
logAfter()...");
joinPoint.getSignature().getName();
}
//사후중고(After Returnning
Advice), 타겟메소드 리턴 후 실행
@AfterReturning(pointcut
= "execution (* onj.aop.aspectjannotation.OnjWorld.onjHello(..))",
returning="result")
public void
logAfterReturning(JoinPoint joinPoint, Object result){
System.out.println("<<<<< Advice -->
logAfterReturning()...");
joinPoint.getSignature().getName();
System.out.println("<<<<< return value is " +
result);
}
//주변충고(Around Advice),
타겟메소드 실행전, 리턴 후 두번 충고 실행
@Around("execution (*
onj.aop.aspectjannotation.OnjWorld.onjHello(..))")
public String
logAround(ProceedingJoinPoint joinPoint) throws Throwable{
System.out.println("<<<<< Advice -->
logAournd()...");
joinPoint.getSignature().getName();
Arrays.toString(joinPoint.getArgs());
System.out.println("<<<<< Around before is
renning!");
joinPoint.proceed();
System.out.println("<<<<< Around after is
renning!)");
return "이 문장으로 원래 타겟메소드
리턴이 대체됨!";
}
//예외충고(Throws Advice),
예외가 발생했을 때 예외전에 충고실행
@AfterThrowing(pointcut =
"execution (* onj.aop.aspectjannotation.OnjWorld.onjHello2(..))", throwing =
"error")
public void
logAfterThrowing(JoinPoint joinPoint, Throwable error){
System.out.println("<<<<< Advice -->
logAfterThrowing()...");
joinPoint.getSignature().getName();
System.out.println("<<<<< Exception "
+error);
}
}
4.
OnjClient.java
package
onj.aop.aspectjannotation;
import
org.springframework.context.ApplicationContext;
import
org.springframework.context.support.ClassPathXmlApplicationContext;
public class OnjClient
{
public static void
main(String[] args) throws Exception{
ApplicationContext ctx
=new
ClassPathXmlApplicationContext("aspectjannotation.xml");
OnjWorld o =
(OnjWorld)ctx.getBean("onjWorld");
o.onjHello();
o.onjHello2();
}
}
5.
src/main/resource/aspectjannotation.xml
<?xml version="1.0"
encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
<aop:aspectj-autoproxy
/>
<bean id="onjWorld"
class="onj.aop.aspectjannotation.OnjWorldImpl" />
<bean id="onjLogger"
class="onj.aop.aspectjannotation.OnjLoggingAspect" />
</beans>
6.[결과]
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in
[jar:file:/C:/java/lib/slf4j-log4j12-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/C:/Documents%20and%20Settings/Administrator/.m2/repository/org/slf4j/slf4j-log4j12/1.6.6/slf4j-log4j12-1.6.6.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an
explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
INFO : org.springframework.context.support.ClassPathXmlApplicationContext -
Refreshing
org.springframework.context.support.ClassPathXmlApplicationContext@6250d2:
startup date [Tue Feb 04 07:20:40 KST 2014]; root of context hierarchy
INFO : org.springframework.beans.factory.xml.XmlBeanDefinitionReader -
Loading XML bean definitions from class path resource
[aspectjannotation.xml]
INFO : org.springframework.beans.factory.support.DefaultListableBeanFactory
- Pre-instantiating singletons in
org.springframework.beans.factory.support.DefaultListableBeanFactory@1518883:
defining beans
[org.springframework.aop.config.internalAutoProxyCreator,onjWorld,onjLogger];
root of factory hierarchy
<<<<< Advice --> logAournd()...
<<<<< Around before is renning!
<<<<< Advice-->logBefore()...
OnJ에오신것을 환영합니다.
<<<<< Around after is renning!)
<<<<< Advice --> logAfter()...
<<<<< Advice --> logAfterReturning()...
<<<<< return value is 이 문장으로 원래 타겟메소드 리턴이 대체됨!
OnJ2에오신것을 환영합니다.
<<<<< Advice --> logAfterThrowing()...
<<<<< Exception java.lang.Exception: OnJ Exception...
Exception in thread "main" java.lang.Exception: OnJ Exception...
at
onj.aop.aspectjannotation.OnjWorldImpl.onjHello2(OnjWorldImpl.java:10)
at
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at
java.lang.reflect.Method.invoke(Unknown Source)
at
org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at
org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:55)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:91)
at
org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at
org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at
onj.aop.aspectjannotation.$Proxy9.onjHello2(Unknown Source)
at
onj.aop.aspectjannotation.OnjClient.main(OnjClient.java:12)
댓글 없음:
댓글 쓰기