본문 바로가기

spring/AOP

AOP 구조를 이해하는 예제1

applicationContext.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"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:p="http://www.springframework.org/schema/p"

xmlns:util="http://www.springframework.org/schema/util"

xmlns:task="http://www.springframework.org/schema/task"

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

http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd

http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd

                http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.2.xsd">          


<bean id="demoServiceTarget1" class="com.demo1.DemoServiceImpl">

<property name="value" value="홍길동"/>

</bean>


<!-- Advice : 공통적으로 사용할 기능을 모아놓은 클래스 -->

<bean id="beforeAdvice" class="com.demo1.BeforeDemoAdvice"/>

<bean id="afterAdvice" class="com.demo1.AfterDemoAdvice"/>


<!-- pointCut : 어떤놈한테 AOP를 실행할지 타겟 설정-->

<bean id="myPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut">

<!-- <property name="pattern" value=".*write.*"/>.* 앞에 0자 이상(결론적으로 write가 들어가면 무조건 실행 -->

<property name="patterns">

<list><!-- 여러개의 메소드 설정 -->

<value>.*write.*</value>

<value>.*set.*</value>

</list>

</property>

</bean>


<!-- advisor : adivice의 기능을 pointcut에서 설정한 타겟에 구현할수 있게 연결해줌-->

<bean id="demoAdvisor1" class="org.springframework.aop.support.DefaultPointcutAdvisor">

<property name="advice" ref="beforeAdvice"/>

<property name="pointcut" ref="myPointcut"/>

</bean>


<bean id="demoAdvisor2" class="org.springframework.aop.support.DefaultPointcutAdvisor">

<property name="advice" ref="afterAdvice"/>

<property name="pointcut" ref="myPointcut"/>

</bean>


<!-- AOP  : advisor를 어디에 적용시켜야 할지 설정 -->

<bean id="demoService1" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="target" ref="demoServiceTarget1"/>

<property name="interceptorNames">

<list>

<value>demoAdvisor1</value>

<value>demoAdvisor2</value>

</list>

</property>

</bean>

</beans>


=========================================================================================================================================================

DemoService.java


package com.demo1;


//AOP는 interface기반으로 작동하므로 interface를 만들어준다.

public interface DemoService {

public void setValue(String value);

public void write();

}

=========================================================================================================================================================

DemoServiceImpl.java

package com.demo1;


public class DemoServiceImpl implements DemoService{

private String message;


@Override

public void setValue(String value) {

message=value;

}


@Override

public void write() {

System.out.println(message);

}

}

=========================================================================================================================================================

BeforeDemoAdvice.java

package com.demo1;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class BeforeDemoAdvice implements MethodBeforeAdvice{

@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
String s1="";
if(args!=null){
for(int i=0; i<args.length; i++)
s1+=" 인수["+i+"] : " + args[i];
}
String s=method.toString()+" 메소드 : " + target+" 에서 호출전. 인수는 " +s1;
System.out.println(s);
}
}

=========================================================================================================================================================

AfterDemoAdvice.java

package com.demo1;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class AfterDemoAdvice implements AfterReturningAdvice {

@Override
public void afterReturning(Object returnValue, Method method, Object[] args,Object target) throws Throwable {
String s=method.toString()+"메소드 : " +target +" 에서 호출 후, 리턴값 : "+ returnValue;
System.out.println(s);
}
}

=========================================================================================================================================================

ResultMain.java

package com.demo1;


import org.springframework.context.support.ClassPathXmlApplicationContext;


public class ResultMain {

public static void main(String[] args){

@SuppressWarnings("resource")

ClassPathXmlApplicationContext ctx= new ClassPathXmlApplicationContext("com/demo1/applicationContext.xml");

DemoService service=(DemoService)ctx.getBean("demoService1");

service.setValue("자바");

service.write();

}

}

=========================================================================================================================================================

ResultMain을 실행시킨 결과


public abstract void com.demo1.DemoService.setValue(java.lang.String) 메소드 : com.demo1.DemoServiceImpl@68a6bcec 에서 호출전. 인수는  인수[0] : 자바

public abstract void com.demo1.DemoService.setValue(java.lang.String)메소드 : com.demo1.DemoServiceImpl@68a6bcec 에서 호출 후, 리턴값 : null

public abstract void com.demo1.DemoService.write() 메소드 : com.demo1.DemoServiceImpl@68a6bcec 에서 호출전. 인수는 

자바

public abstract void com.demo1.DemoService.write()메소드 : com.demo1.DemoServiceImpl@68a6bcec 에서 호출 후, 리턴값 : null



// 설명

setValue메소드를 실행하기 직전 MethodBeforeAdvice가 implement된 BeforeDemoAdvice.java가 한번 실행된다. 그래서 첫번째 줄의 결과가 찍혔다.

setValue메소드를 실행하고 난후 AfterReturningAdivice가 implement된 AfterDemoAdvice.java가 다시 한번 실행된다. 그래서 두번째 줄의 결과가 찍혔다.

write메소드를 실행하기 직전 MethodBeforeAdvice가 implement된 BeforeDemoAdvice.java가 한번 실행된다. 그래서 세번째 줄의 결과가 찍혔다.

write메소드의 실행결과가 찍혔다.

write메소드를 실행하고 난후 AfterReturningAdivice가 implement된 AfterDemoAdvice.java가 다시 한번 실행된다. 그래서 네번째 줄의 결과가 찍혔다.