๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Spring

AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ XML ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง AOP ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

by Leica 2020. 4. 27.
๋ฐ˜์‘ํ˜•

AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ XML ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง AOP ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

AOP๋ž€?

- Aspect Oriented Programming : ๊ด€์  ์ง€ํ–ฅ ํ”„๋กœ๊ทธ๋ž˜๋ฐ
- OOP ์™€ ๋ถ„๋ฆฌ๋œ ๊ฐœ๋…์ด ์•„๋‹ˆ๋ผ, OOP์— ๊ธฐ์ดˆ๋ฅผ ๋‘๋Š” ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹
- ํ•˜๋‚˜์˜ ํ”„๋กœ๊ทธ๋žจ์„ ๊ด€์ (ํ˜น์€ ๊ด€์‹ฌ์‚ฌ)๋ผ๋Š” ๋…ผ๋ฆฌ์ ์ธ ๋‹จ์œ„๋กœ ๋ถ„๋ฆฌํ•˜์—ฌ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐœ๋…
- ๋กœ๊น…, ๊ฐ์‚ฌ, ์„ ์–ธ์  ํŠธ๋žœ์ ์…˜, ๋ณด์•ˆ, ์บ์‹ฑ ๋“ฑ ๋‹ค์–‘ํ•œ ๊ณณ์—์„œ ์‚ฌ์šฉ๋œ๋‹ค.

AOP ์šฉ์–ด

- Joint Point : ๋ชจ๋“ˆ์ด ์‚ฝ์ž…๋˜์–ด ๋™์ž‘ํ•˜๊ฒŒ ๋˜๋Š” ํŠน์ • ์œ„์น˜(๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๋“ฑ)
-
Point Cut : ๋‹ค์–‘ํ•œ Joint Point ์ค‘์— ์–ด๋–ค ๊ฒƒ์„ ์‚ฌ์šฉํ• ์ง€ ์„ ํƒ
- Advice : Joint Point์— ์‚ฝ์ž…๋˜์–ด ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋Š” ์ฝ”๋“œ
-
Weaving : Advice๋ฅผ ํ•ต์‹ฌ ๋กœ์ง ์ฝ”๋“œ์— ์ ์šฉํ•˜๋Š” ๊ฒƒ
- Aspect : Point Cut + Advice

Spring AOP Advice ์ข…๋ฅ˜

- before : ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ „์— ๋™์ž‘ํ•˜๋Š” Advice
-
after-returning : ์˜ˆ์™ธ ์—†์ด ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์ด ์™„๋ฃŒ๋˜๋ฉด ๋™์ž‘ํ•˜๋Š” Advice
-
after-throwing : ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ ๋™์ž‘ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋™์ž‘ํ•˜๋Š” Advice
-
after : ์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ์˜ ๋™์ž‘์ด ์™„๋ฃŒ๋˜๋ฉด ๋™์ž‘ํ•˜๋Š” Advice
-
around : ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์ „๊ณผ ํ›„์— ๋™์ž‘ํ•˜๋Š” Advice

 

Spring AOP ๊ตฌํ˜„

AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ Spring AOP ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ XML์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ๊ณผ @AspectJ ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

๋ณธ ๊ธ€์—์„œ๋Š” XML ๊ธฐ๋ฐ˜์˜ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณธ๋‹ค.

 

๊ด€๋ จ ๊ธ€ - AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง AOP ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

 

1) ๊ณตํ†ต ์‚ฌํ•ญ

โ‘  AspectJ Weaver ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.5</version>
</dependency>

 

โ‘ก ๊ด€์‹ฌ์‚ฌ๋กœ ์„ค์ •ํ•  ์ฝ”๋“œ ์ž‘์„ฑ

public class TestBean {
	
	public int method1() {
		System.out.println("method1 ํ˜ธ์ถœ");
		
		return 100;
	}
}

๊ด€์‹ฌ์‚ฌ๋กœ ์„ค์ •ํ•  ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•œ๋‹ค.

TestBean ํด๋ž˜์Šค์˜ method1() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์„ ๊ด€์‹ฌ์‚ฌ๋กœ ์„ค์ •ํ•  ๊ฒƒ์ด๋‹ค.

๋‹ค์–‘ํ•œ ์ผ€์ด์Šค๋ฅผ ํ…Œ์ŠคํŠธํ•˜๊ธฐ ์œ„ํ•ด intํ˜• ๋ฐ์ดํ„ฐ๋ฅผ ๋ฆฌํ„ดํ•˜๋„๋ก ํ•˜์˜€๋‹ค.

 

public class MainClass {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml");
		
		TestBean bean1 = ctx.getBean("testBean", TestBean.class);
		
		int a1 = bean1.method1();
		System.out.printf("a1 : %d\n", a1);
		
		ctx.close();
	}
}

main ๋ฉ”์†Œ๋“œ์—์„œ ApplicationContext ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•˜๊ณ  TestBean ๋นˆ ๊ฐ์ฒด๋ฅผ ๊ฐ€์ ธ์˜จ ๋’ค TestBean ํด๋ž˜์Šค์˜ method1() ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

method1 ํ˜ธ์ถœ
a1 : 100

Spring AOP๋ฅผ ์‚ฌ์šฉํ•ด method1()์˜ ํ˜ธ์ถœ์„ ๊ด€์‹ฌ์‚ฌ๋กœ ์„ค์ •ํ•˜์—ฌ method1() ํ˜ธ์ถœ ์ „, ํ›„์— ํŠน์ • ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋‹ค.

 

โ‘ข Advisor ํด๋ž˜์Šค ์ƒ์„ฑ

public class AdvisorClass {

}

Advice๋“ค์„ ๋ชจ์•„๋†“์€ ๊ฒƒ์„ Advisor๋ผ๊ณ  ํ•œ๋‹ค.

์ด ํด๋ž˜์Šค์— method1()์˜ ํ˜ธ์ถœ ์ „, ํ›„์— ํ˜ธ์ถœํ•  ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•  ๊ฒƒ์ด๋‹ค.

 

2) 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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- ๋นˆ ๋“ฑ๋ก -->                    
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>  
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>
    
    	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>
		</aop:aspect>
	</aop:config>
</beans>

์Šคํ”„๋ง xml ์„ค์ •์— aop ๋„ค์ž„์ŠคํŽ˜์ด์Šค๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  TestBean, AdvisorClass ํด๋ž˜์Šค๋ฅผ ๋นˆ์œผ๋กœ ๋“ฑ๋กํ•œ๋‹ค.

<aop:config>๋กœ AOP ์„ค์ •์„ ํ•œ๋‹ค.

<aop:aspect>์˜ ref ์†์„ฑ์— advisor ํด๋ž˜์Šค์˜ ๋นˆ id๋ฅผ ์ง€์ •ํ•œ๋‹ค.

<aop:pointcut>์˜ expression์— execution ๋ช…์‹œ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ๊ด€์‹ฌ์‚ฌ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

execution(* method1())๊ณผ ๊ฐ™์ด ์„ค์ •ํ•˜๋ฉด ๋ชจ๋“  ํŒจํ‚ค์ง€, ๋ชจ๋“  ํด๋ž˜์Šค์˜ method1() ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ์ด ๊ด€์‹ฌ์‚ฌ๊ฐ€ ๋œ๋‹ค.

 

๐Ÿ”— ์ฐธ๊ณ  - [AspectJ Weaver] execution ์ง€์‹œ์ž ์„ค์ • ๋ฐฉ๋ฒ• ์ •๋ฆฌ

 

โ‘  Before - ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์ „์— ๋™์ž‘

public class AdvisorClass {
	
    	// before advice
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}
}

advisor ํด๋ž˜์Šค์— ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์ „์— ํ˜ธ์ถœํ•  ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- ๋นˆ ๋“ฑ๋ก -->                    
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>  
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>
    
    	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>
            
            		<!-- before -->
            		<aop:before method="beforeMethod" pointcut-ref="point1"/>
		</aop:aspect>
	</aop:config>
</beans>

<aop:before>๋กœ before advice๋ฅผ ์„ค์ •ํ•œ๋‹ค.

method์— advisor ํด๋ž˜์Šค์— ๊ตฌํ˜„ํ•œ ๋ฉ”์†Œ๋“œ์˜ ์ด๋ฆ„์„, pointcut-ref์— ์œ„์—์„œ ์„ค์ •ํ•œ <aop:pointcut>์˜ id๋ฅผ ์ง€์ •ํ•œ๋‹ค.

์ด์ œ method1() ํ˜ธ์ถœ์— ๋Œ€ํ•œ ๊ด€์‹ฌ์‚ฌ ์„ค์ •, before advice ๊ตฌํ˜„ ๋ฐ ์„ค์ •์ด ์™„๋ฃŒ๋˜์—ˆ๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

beforeMethod ํ˜ธ์ถœ
method1 ํ˜ธ์ถœ
a1 : 100

 

โ‘ก After Advice - ์˜ˆ์™ธ ๋ฐœ์ƒ ์—ฌ๋ถ€์— ๊ด€๊ณ„์—†์ด ํ˜ธ์ถœ๋œ ๋ฉ”์†Œ๋“œ์˜ ๋™์ž‘์ด ์™„๋ฃŒ๋˜๋ฉด ๋™์ž‘

public class AdvisorClass {
	
    	// before advice
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}
	
    	// after advice
	public void afterMethod() {
		System.out.println("afterMethod ํ˜ธ์ถœ");
	}
}

advisor ํด๋ž˜์Šค์— after advice ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- ๋นˆ ๋“ฑ๋ก -->                    
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>  
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>
    
    	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>
            
            		<!-- before -->
            		<aop:before method="beforeMethod" pointcut-ref="point1"/>
            
            		<!-- after -->
            		<aop:after method="afterMethod" pointcut-ref="point1"/>
		</aop:aspect>
	</aop:config>
</beans>

<aop:after>๋กœ after advice๋ฅผ ์„ค์ •ํ•œ๋‹ค.

์„ค์ • ๋ฐฉ๋ฒ•์€ <aop:before>์™€ ๋™์ผํ•˜๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

beforeMethod ํ˜ธ์ถœ
method1 ํ˜ธ์ถœ
afterMethod ํ˜ธ์ถœ
a1 : 100

 

โ‘ข Around Advice - ๋ฉ”์†Œ๋“œ ํ˜ธ์ถœ ์ „๊ณผ ํ›„์— ๋™์ž‘

import org.aspectj.lang.ProceedingJoinPoint;

public class AdvisorClass {
	
	// before advice
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}
	
	// after advice
	public void afterMethod() {
		System.out.println("afterMethod ํ˜ธ์ถœ");
	}
	
	// around advice
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ1");
		
		// ์›๋ž˜์˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
		Object obj = pjp.proceed();
		
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		
		return obj;
	}
}

advisor ํด๋ž˜์Šค์— around adivce ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

์ด ๋•Œ๋Š” org.aspectj.lang.ProceedingJoinPoint๋ฅผ ๋ฉ”์†Œ๋“œ์˜ ์ธ์ž๋กœ ๋ฐ›์•„์„œ ์ด ๊ฐ์ฒด์˜ proceed()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์ž‘์—… ์ค‘๊ฐ„์— ์›๋ž˜ ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ•œ๋‹ค.

์›๋ž˜ ๋ฉ”์†Œ๋“œ๊ฐ€ ๋ฆฌํ„ด๊ฐ’์ด ์žˆ์„ ๊ฒฝ์šฐ Object ํƒ€์ž…์œผ๋กœ ๋ฐ›์•„์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<!-- ๋นˆ ๋“ฑ๋ก -->
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>
	
	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>
			
			<!-- before -->
			<aop:before method="beforeMethod" pointcut-ref="point1"/>
			
			<!-- after -->
			<aop:after method="afterMethod" pointcut-ref="point1"/>
			
			<!-- around -->
			<aop:around method="aroundMethod" pointcut-ref="point1"/>
		</aop:aspect>
	</aop:config>
</beans>

<aop:around>๋กœ after advice๋ฅผ ์„ค์ •ํ•œ๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

beforeMethod ํ˜ธ์ถœ
aroundMethod ํ˜ธ์ถœ1
method1 ํ˜ธ์ถœ
aroundMethod ํ˜ธ์ถœ 2
afterMethod ํ˜ธ์ถœ
a1 : 100

 

โ‘ฃ After-Returning Advice - ์˜ˆ์™ธ ์—†์ด ํ˜ธ์ถœ๋œ ๋ฉ”์†Œ๋“œ์˜ ๋™์ž‘์ด ์™„๋ฃŒ๋˜๋ฉด ๋™์ž‘

import org.aspectj.lang.ProceedingJoinPoint;

public class AdvisorClass {

	// before advice
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}

	// after advice
	public void afterMethod() {
		System.out.println("afterMethod ํ˜ธ์ถœ");
	}

	// around advice
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ1");
		
		// ์›๋ž˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
		Object obj = pjp.proceed();
		
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		
		return obj;
	}

	// after-returning advice
	public void afterReturningMethod() {
		System.out.println("afterReturningMethod ํ˜ธ์ถœ");
	}
}

After advice ๋ฉ”์†Œ๋“œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•์€ before, after์™€ ๋‹ค๋ฅด์ง€ ์•Š๋‹ค.

๋งค๊ฐœ๋ณ€์ˆ˜ ์—†์ด ์ˆ˜ํ–‰ํ•  ์ž‘์—…์„ ๊ตฌํ˜„ํ•˜๋ฉด ๋œ๋‹ค.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- ๋นˆ ๋“ฑ๋ก -->
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>

	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>

			<!-- before -->
			<aop:before method="beforeMethod" pointcut-ref="point1"/>

			<!-- after -->
			<aop:after method="afterMethod" pointcut-ref="point1"/>

			<!-- around -->
			<aop:around method="aroundMethod" pointcut-ref="point1"/>

			<!-- after-returning -->
			<aop:after-returning method="afterReturningMethod" pointcut-ref="point1"/>
		</aop:aspect>
	</aop:config>
</beans>

<aop:after-returning>์œผ๋กœ ์„ค์ •ํ•œ๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

beforeMethod ํ˜ธ์ถœ
aroundMethod ํ˜ธ์ถœ1
method1 ํ˜ธ์ถœ
afterReturningMethod ํ˜ธ์ถœ
aroundMethod ํ˜ธ์ถœ 2
afterMethod ํ˜ธ์ถœ
a1 : 100

 

โ‘ค After-Throwing Advice - ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ ๋™์ž‘ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๋™์ž‘

import org.aspectj.lang.ProceedingJoinPoint;

public class AdvisorClass {

	// before advice
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}

	// after advice
	public void afterMethod() {
		System.out.println("afterMethod ํ˜ธ์ถœ");
	}

	// around advice
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ1");
		
		// ์›๋ž˜์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
		Object obj = pjp.proceed();
		
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		
		return obj;
	}

	// after-returning advice
	public void afterReturningMethod() {
		System.out.println("afterReturningMethod ํ˜ธ์ถœ");
	}

	// after-throwing advice
	public void afterThrowingMethod(Throwable e1) {
		System.out.println("afterThrowingMethod ํ˜ธ์ถœ");
		System.out.println(e1);
	}
}

After-throwing advice ๋ฉ”์†Œ๋“œ๋Š” ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ๋ฅผ ๋ฉ”์†Œ๋“œ ์•„๊ทœ๋จผํŠธ๋กœ ๋ฐ›์•„ ์˜ˆ์™ธ ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋“ฑ์˜ ์ถ”๊ฐ€ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	                    http://www.springframework.org/schema/beans/spring-beans.xsd
	                    http://www.springframework.org/schema/context
	                    http://www.springframework.org/schema/context/spring-context.xsd
	                    http://www.springframework.org/schema/aop
	                    http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- ๋นˆ ๋“ฑ๋ก -->
	<bean id='testBean' class='com.atoz_develop.beans.TestBean'/>
	<bean id='advisorClass' class='com.atoz_develop.advisor.AdvisorClass'/>

	<!-- AOP ์„ค์ • -->
	<aop:config>
		<aop:aspect ref='advisorClass'>
			<aop:pointcut id="point1" expression="execution(* method1())"/>

			<!-- before -->
			<aop:before method="beforeMethod" pointcut-ref="point1"/>

			<!-- after -->
			<aop:after method="afterMethod" pointcut-ref="point1"/>

			<!-- around -->
			<aop:around method="aroundMethod" pointcut-ref="point1"/>

			<!-- after-returning -->
			<aop:after-returning method="afterReturningMethod" pointcut-ref="point1"/>

			<!-- after-throwing -->
			<aop:after-throwing method="afterThrowingMethod" pointcut-ref="point1" throwing="e1"/>
		</aop:aspect>
	</aop:config>
</beans>

after-throwing advice๋Š” <aop:after-throwing>์œผ๋กœ ์„ค์ •ํ•˜๋Š”๋ฐ, ์˜ˆ์™ธ ๊ฐ์ฒด๋ฅผ after-throwing advice ๋ฉ”์†Œ๋“œ์—์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ๋„๋ก throwing ์†์„ฑ์„ ์‚ฌ์šฉํ•ด์„œ ๋ฉ”์†Œ๋“œ์˜ ์˜ˆ์™ธ ์•„๊ทœ๋จผํŠธ ์ด๋ฆ„์„ ์ง€์ •ํ•œ๋‹ค.

 

public class TestBean {
	
	public int method1() {
		System.out.println("method1 ํ˜ธ์ถœ");
		
		int a1 = 10 / 0;	// ์˜ˆ์™ธ ๋ฐœ์ƒ
		
		return 100;
	}
}

ํ…Œ์ŠคํŠธ๋ฅผ ์œ„ํ•ด method1()์—์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

 

๐Ÿ–ฅ ์‹คํ–‰ ๊ฒฐ๊ณผ

beforeMethod ํ˜ธ์ถœ
aroundMethod ํ˜ธ์ถœ1
method1 ํ˜ธ์ถœ
afterThrowingMethod ํ˜ธ์ถœ
java.lang.ArithmeticException: / by zero
afterMethod ํ˜ธ์ถœ
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.atoz_develop.beans.TestBean.method1(TestBean.java:8)
	at com.atoz_develop.beans.TestBean$$FastClassBySpringCGLIB$$13abe977.invoke(<generated>)
	at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
	at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88)
	at com.atoz_develop.advisor.AdvisorClass.aroundMethod(AdvisorClass.java:22)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644)
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633)
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.AspectJAfterAdvice.invoke(AspectJAfterAdvice.java:47)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
	at com.atoz_develop.beans.TestBean$$EnhancerBySpringCGLIB$$b59cccdc.method1(<generated>)
	at com.atoz_develop.main.MainClass.main(MainClass.java:15)

Process finished with exit code 1

๊ด€์‹ฌ์‚ฌ๋กœ ์„ค์ •ํ•œ method1()  ํ˜ธ์ถœ ์ค‘ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•˜์ž after-returning advice ๋ฉ”์†Œ๋“œ ๋Œ€์‹  after-throwing advice ๋ฉ”์†Œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

ํ…Œ์ŠคํŠธ ํ›„ method1()์—์„œ ์˜ˆ์™ธ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ•œ ์ฝ”๋“œ๋ฅผ ์‚ญ์ œํ•˜๋Š” ๊ฒƒ์„ ์žŠ์ง€ ๋ง์ž.

 

๊ด€๋ จ ๊ธ€

- AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง AOP ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

- [AspectJ Weaver] execution ์ง€์‹œ์ž ์„ค์ • ๋ฐฉ๋ฒ• ์ •๋ฆฌ

 

References

์ธํ”„๋Ÿฐ - ์†Œํ”„ํŠธ์บ ํผ์Šค ์Šคํ”„๋ง ํ”„๋ ˆ์ž„์›Œํฌ ๊ฐœ๋ฐœ์ž๋ฅผ ์œ„ํ•œ ์‹ค์Šต์„ ํ†ตํ•œ ์ž…๋ฌธ ๊ณผ์ •

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€