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

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

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

AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ ์• ๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง 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 ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•˜๋Š” ๊ฒƒ์œผ๋กœ ๋‚˜๋‰œ๋‹ค.

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

 

๊ด€๋ จ ๊ธ€ - AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ XML ๊ธฐ๋ฐ˜์˜ ์Šคํ”„๋ง 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>

 

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

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

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

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

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

 

public class MainClass {

	public static void main(String[] args) {
		AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(BeanConfigClass.class);
		
		TestBean bean1 = ctx.getBean(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 ํด๋ž˜์Šค ์ƒ์„ฑ

import org.aspectj.lang.annotation.Aspect;

@Aspect
@Component
public class AdvisorClass {

}

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

@Aspect ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์—ฌ advisor ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

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

 

2) ์• ๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•œ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

์Šคํ”„๋ง ์„ค์ • ํด๋ž˜์Šค

@Configuration
@ComponentScan(basePackages = {"com.atoz_develop.beans", "com.atoz_develop.advisor"})
@EnableAspectJAutoProxy
public class BeanConfigClass {

}

์Šคํ”„๋ง ์„ค์ • ํด๋ž˜์Šค์— @EnableAspectJAutoProxy๋ฅผ ๋ถ™์—ฌ์ค€๋‹ค.

@Aspect๊ฐ€ ๋ถ™์–ด์žˆ๋Š” advisor ํด๋ž˜์Šค์˜ ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ„์„ํ•ด์„œ AOP ์…‹ํŒ…์„ ํ•˜๋„๋ก ํ•˜๋Š” ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์Šคํ”„๋ง XML ์„ค์ • ์‚ฌ์šฉ ์‹œ์—๋Š” <aop:aspectj-autoproxy/>๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

 

๐Ÿ“ AspectJ Weaver ์• ๋…ธํ…Œ์ด์…˜ AOP ์„ค์ •ํ•˜๊ธฐ
์Šคํ”„๋ง ์ž๋ฐ” ์„ค์ • ์‚ฌ์šฉ ์‹œ : @EnableAspectJAutoProxy
์Šคํ”„๋ง XML ์„ค์ • ์‚ฌ์šฉ ์‹œ : <aop:aspectj-autoproxy/>

AOP๋ฅผ ์• ๋…ธํ…Œ์ด์…˜์œผ๋กœ ์„ค์ •ํ•˜๋ฏ€๋กœ ์Šคํ”„๋ง ์„ค์ • ํด๋ž˜์Šค์— ํ•ด์ค„ ๊ฒƒ์€ ์ด๊ฒŒ ๋์ด๋‹ค.

AspectJ Weaver๋ฅผ ์‚ฌ์šฉํ•œ XML ๊ธฐ๋ฐ˜์˜ AOP๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๊ณผ ๋‹ฌ๋ฆฌ AOP ์„ค์ •์„ ์Šคํ”„๋ง ์„ค์ • ํŒŒ์ผ์— ์ž‘์„ฑํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด์ œ before, after, around, after-returning, after-throwing advice ๋ฉ”์†Œ๋“œ๋ฅผ ์ฐจ๋ก€๋กœ ๊ตฌํ˜„ํ•˜๊ณ  ํ…Œ์ŠคํŠธํ•ด๋ณด์ž.

 

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

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
@Component
public class AdvisorClass {
	
	// before advice
	@Before("execution(* method1())")
	public void beforeMethod() {
		System.out.println("beforeMethod ํ˜ธ์ถœ");
	}
}

advisor ํด๋ž˜์Šค์—์„œ @Before ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด before advice ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

@Before() ์•ˆ์— execution ๋ช…์‹œ์ž๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŠน์ • ๊ด€์‹ฌ์‚ฌ๋ฅผ ์ง€์ •ํ•œ๋‹ค.

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

 

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

 

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

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

 

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

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
@Component
public class AdvisorClass {

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

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

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

 

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

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

 

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

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
@Component
public class AdvisorClass {

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

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

	// around advice
	@Around("execution(* method1())")
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ 1");
		Object result = pjp.proceed();
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		return result;
	}
}

advisor ํด๋ž˜์Šค์—์„œ @Around ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด around advice ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

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

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

 

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

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

 

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

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
@Component
public class AdvisorClass {

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

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

	// around advice
	@Around("execution(* method1())")
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ 1");
		Object result = pjp.proceed();
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		return result;
	}

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

advisor ํด๋ž˜์Šค์—์„œ @AfterReturning ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด after-returning advice ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

 

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

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

 

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

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
@Component
public class AdvisorClass {

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

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

	// around advice
	@Around("execution(* method1())")
	public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("aroundMethod ํ˜ธ์ถœ 1");
		Object result = pjp.proceed();
		System.out.println("aroundMethod ํ˜ธ์ถœ 2");
		return result;
	}

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

	// after-throwing advice
	@AfterThrowing("execution(* method1())")
	public void afterThrowingMethod() {
		System.out.println("afterThrowing ํ˜ธ์ถœ");
	}
}

advisor ํด๋ž˜์Šค์—์„œ @AfterThrowing ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด after-throwing advice ๋ฉ”์†Œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•œ๋‹ค.

 

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

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

 

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

aroundMethod ํ˜ธ์ถœ 1
beforeMethod ํ˜ธ์ถœ
method1 ํ˜ธ์ถœ
afterMethod ํ˜ธ์ถœ
afterThrowing ํ˜ธ์ถœ
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at com.atoz_develop.beans.TestBean1.method1(TestBean1.java:11)
	at com.atoz_develop.beans.TestBean1$$FastClassBySpringCGLIB$$61d1459a.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.framework.adapter.MethodBeforeAdviceInterceptor.invoke(MethodBeforeAdviceInterceptor.java:56)
	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:32)
	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.AfterReturningAdviceInterceptor.invoke(AfterReturningAdviceInterceptor.java:55)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
	at org.springframework.aop.aspectj.AspectJAfterThrowingAdvice.invoke(AspectJAfterThrowingAdvice.java:62)
	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.TestBean1$$EnhancerBySpringCGLIB$$dba43ddc.method1(<generated>)
	at com.atoz_develop.main.MainClass.main(MainClass.java:29)

Process finished with exit code 1

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

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

 

๊ด€๋ จ ๊ธ€

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

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

 

References

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

๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€