๋งค๊ฐ๋ณ์ ์ ๋ฌ
this, target, args, @target, @within, @annotation, @args
์์ ํฌ์ธํธ์ปท ์ง์์๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ด๋๋ฐ์ด์ค์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ ํํ๋ก ์ฌ์ฉํฉ๋๋ค.
@Before("allMember() && args(argName, ..)")
fun log(argName: String) {
println("[log] argName = {${argName}}")
}
ํฌ์ธํธ์ปท์์์ ์ด๋ฆ๊ณผ ๋งค๊ฐ๋ณ์์ ์ด๋ฆ์ ๋ง์ถ์ด์ผ ํฉ๋๋ค.
์์ ์์์์๋ argName์ผ๋ก ๋ง์ถ์์ต๋๋ค.
์ถ๊ฐ๋ก ํ์ ์ด ๋ฉ์๋์ ์ง์ ๋ ํ์ ์ผ๋ก ์ง์ ๋ฉ๋๋ค.
์ฆ args(argName, ..)๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋๋ ๊ฒ์ ๋๋ค.
args(String, ..)
์์ ์ฝ๋
@Target(CLASS)//ํด๋์ค์ ๋ถ์
@Retention(RUNTIME)
annotation class ClassAop()
@Target(FUNCTION)
@Retention(RUNTIME)
annotation class MethodAop(
val value: String
)
interface MemberService {
fun hello(param: String): String
}
package hello.advanced.aop.member
import hello.advanced.aop.member.anno.ClassAop
import hello.advanced.aop.member.anno.MethodAop
import org.springframework.stereotype.Component
@ClassAop
@Component
class MemberServiceImpl : MemberService{
@MethodAop("test value")
override fun hello(param: String): String {
return "ok"
}
fun internal(param: String): String {
return "ok"
}
}
package hello.advanced.aop.member
import hello.advanced.aop.member.anno.MethodAop
interface MemberService {
@MethodAop("test value")
fun hello(param: String): String
}
package hello.advanced.aop.member
import org.springframework.stereotype.Component
@Component
class MemberServiceImpl : MemberService{
override fun hello(param: String): String {
return "ok"
}
fun internal(param: String): String {
return "ok"
}
}
package hello.advanced.pointcut
import hello.advanced.aop.member.MemberService
import hello.advanced.aop.member.anno.ClassAop
import hello.advanced.aop.member.anno.MethodAop
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.stereotype.Component
@SpringBootTest
class ParamTest(
@Autowired val memberService: MemberService
) {
@Test
fun success() {
println("memberService Proxy=${memberService.javaClass}")
memberService.hello("helloA")
}
}
@Aspect
@Component
class ParameterAspect {
@Pointcut("execution(* hello.advanced.aop.member..*.*(..))")
fun allMember() {}
@Around("allMember()")
fun logArgs1(joinPoint: ProceedingJoinPoint): Any? {
val arg = joinPoint.args[0]
println("[logArgs1]${joinPoint.signature} ${arg}")
return joinPoint.proceed()
}
@Around("allMember() && args(argName, ..) ")
fun logArgs2(joinPoint: ProceedingJoinPoint, argName: Any): Any? {
println("[logArgs2]${joinPoint.signature} ${argName}")
return joinPoint.proceed()
}
@Before("allMember() && args(arg, ..) ")
fun logArgs3(arg: Any) {
println("[logArgs3] ${arg}")
}
@Before("allMember() && this(obj) ")
fun thisArgs(joinPoint: JoinPoint, obj: MemberService) {//๋์ ํด๋์ค ํ์
์ง์ ์ง์ ๊ฐ๋ฅ
//== this๋ ์คํ๋ง์ ๋ฑ๋ก๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ ==//
println("[this] ${joinPoint.signature}, obj = ${obj.javaClass}")
}
@Before("allMember() && target(obj) ")
fun targetArgs(joinPoint: JoinPoint, obj: MemberService) {//๋์ ํด๋์ค ํ์
์ง์ ์ง์ ๊ฐ๋ฅ
//== target์ ์ค์ ๋์ ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ ==//
println("[target] ${joinPoint.signature}, obj = ${obj.javaClass}")
}
@Before("allMember() && @target(annotation) ")
fun atTarget(joinPoint: JoinPoint, annotation: ClassAop) {
println("[@target] ${joinPoint.signature}, obj = ${annotation}")
}
@Before("allMember() && @within(annotation) ")
fun atWithin(joinPoint: JoinPoint, annotation: ClassAop) {
println("[@within] ${joinPoint.signature}, obj = ${annotation}")
}
@Before("allMember() && @annotation(annotation) ")
fun atAnnotation(joinPoint: JoinPoint, annotation: MethodAop) {
//== ์ ๋
ธํ
์ด์
์ ์์ฑ๊ฐ๋ ์ถ์ถ ๊ฐ๋ฅ ==//
println("[@annotation] ${joinPoint.signature}, obj = ${annotation}, annotationValue = ${annotation.value}")
}
}

Reference
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-pointcuts
Core Technologies
In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do
docs.spring.io
์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ณ ๊ธํธ - ์ธํ๋ฐ | ๊ฐ์
์คํ๋ง์ ํต์ฌ ์๋ฆฌ์ ๊ณ ๊ธ ๊ธฐ์ ๋ค์ ๊น์ด์๊ฒ ํ์ตํ๊ณ , ์คํ๋ง์ ์์ ์๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค., - ๊ฐ์ ์๊ฐ | ์ธํ๋ฐ...
www.inflearn.com
'๐๏ธ Spring > AOP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[AOP] ์ด๋๋ฐ์ด์ค์ ์ข ๋ฅ (0) | 2022.08.03 |
---|---|
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (10) - target (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (9) - this (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (8) - bean (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (7) - @args (0) | 2022.08.02 |
๋งค๊ฐ๋ณ์ ์ ๋ฌ
this, target, args, @target, @within, @annotation, @args
์์ ํฌ์ธํธ์ปท ์ง์์๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ์ด๋๋ฐ์ด์ค์ ๋งค๊ฐ๋ณ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค.
๋ค์๊ณผ ๊ฐ์ ํํ๋ก ์ฌ์ฉํฉ๋๋ค.
@Before("allMember() && args(argName, ..)")
fun log(argName: String) {
println("[log] argName = {${argName}}")
}
ํฌ์ธํธ์ปท์์์ ์ด๋ฆ๊ณผ ๋งค๊ฐ๋ณ์์ ์ด๋ฆ์ ๋ง์ถ์ด์ผ ํฉ๋๋ค.
์์ ์์์์๋ argName์ผ๋ก ๋ง์ถ์์ต๋๋ค.
์ถ๊ฐ๋ก ํ์ ์ด ๋ฉ์๋์ ์ง์ ๋ ํ์ ์ผ๋ก ์ง์ ๋ฉ๋๋ค.
์ฆ args(argName, ..)๋ ๋ค์๊ณผ ๊ฐ์ด ์ ์๋๋ ๊ฒ์ ๋๋ค.
args(String, ..)
์์ ์ฝ๋
@Target(CLASS)//ํด๋์ค์ ๋ถ์
@Retention(RUNTIME)
annotation class ClassAop()
@Target(FUNCTION)
@Retention(RUNTIME)
annotation class MethodAop(
val value: String
)
interface MemberService {
fun hello(param: String): String
}
package hello.advanced.aop.member
import hello.advanced.aop.member.anno.ClassAop
import hello.advanced.aop.member.anno.MethodAop
import org.springframework.stereotype.Component
@ClassAop
@Component
class MemberServiceImpl : MemberService{
@MethodAop("test value")
override fun hello(param: String): String {
return "ok"
}
fun internal(param: String): String {
return "ok"
}
}
package hello.advanced.aop.member
import hello.advanced.aop.member.anno.MethodAop
interface MemberService {
@MethodAop("test value")
fun hello(param: String): String
}
package hello.advanced.aop.member
import org.springframework.stereotype.Component
@Component
class MemberServiceImpl : MemberService{
override fun hello(param: String): String {
return "ok"
}
fun internal(param: String): String {
return "ok"
}
}
package hello.advanced.pointcut
import hello.advanced.aop.member.MemberService
import hello.advanced.aop.member.anno.ClassAop
import hello.advanced.aop.member.anno.MethodAop
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.stereotype.Component
@SpringBootTest
class ParamTest(
@Autowired val memberService: MemberService
) {
@Test
fun success() {
println("memberService Proxy=${memberService.javaClass}")
memberService.hello("helloA")
}
}
@Aspect
@Component
class ParameterAspect {
@Pointcut("execution(* hello.advanced.aop.member..*.*(..))")
fun allMember() {}
@Around("allMember()")
fun logArgs1(joinPoint: ProceedingJoinPoint): Any? {
val arg = joinPoint.args[0]
println("[logArgs1]${joinPoint.signature} ${arg}")
return joinPoint.proceed()
}
@Around("allMember() && args(argName, ..) ")
fun logArgs2(joinPoint: ProceedingJoinPoint, argName: Any): Any? {
println("[logArgs2]${joinPoint.signature} ${argName}")
return joinPoint.proceed()
}
@Before("allMember() && args(arg, ..) ")
fun logArgs3(arg: Any) {
println("[logArgs3] ${arg}")
}
@Before("allMember() && this(obj) ")
fun thisArgs(joinPoint: JoinPoint, obj: MemberService) {//๋์ ํด๋์ค ํ์
์ง์ ์ง์ ๊ฐ๋ฅ
//== this๋ ์คํ๋ง์ ๋ฑ๋ก๋ ํ๋ก์ ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ ==//
println("[this] ${joinPoint.signature}, obj = ${obj.javaClass}")
}
@Before("allMember() && target(obj) ")
fun targetArgs(joinPoint: JoinPoint, obj: MemberService) {//๋์ ํด๋์ค ํ์
์ง์ ์ง์ ๊ฐ๋ฅ
//== target์ ์ค์ ๋์ ๊ฐ์ฒด๊ฐ ์ถ๋ ฅ ==//
println("[target] ${joinPoint.signature}, obj = ${obj.javaClass}")
}
@Before("allMember() && @target(annotation) ")
fun atTarget(joinPoint: JoinPoint, annotation: ClassAop) {
println("[@target] ${joinPoint.signature}, obj = ${annotation}")
}
@Before("allMember() && @within(annotation) ")
fun atWithin(joinPoint: JoinPoint, annotation: ClassAop) {
println("[@within] ${joinPoint.signature}, obj = ${annotation}")
}
@Before("allMember() && @annotation(annotation) ")
fun atAnnotation(joinPoint: JoinPoint, annotation: MethodAop) {
//== ์ ๋
ธํ
์ด์
์ ์์ฑ๊ฐ๋ ์ถ์ถ ๊ฐ๋ฅ ==//
println("[@annotation] ${joinPoint.signature}, obj = ${annotation}, annotationValue = ${annotation.value}")
}
}

Reference
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#aop-pointcuts
Core Technologies
In the preceding scenario, using @Autowired works well and provides the desired modularity, but determining exactly where the autowired bean definitions are declared is still somewhat ambiguous. For example, as a developer looking at ServiceConfig, how do
docs.spring.io
์คํ๋ง ํต์ฌ ์๋ฆฌ - ๊ณ ๊ธํธ - ์ธํ๋ฐ | ๊ฐ์
์คํ๋ง์ ํต์ฌ ์๋ฆฌ์ ๊ณ ๊ธ ๊ธฐ์ ๋ค์ ๊น์ด์๊ฒ ํ์ตํ๊ณ , ์คํ๋ง์ ์์ ์๊ฒ ์ฌ์ฉํ ์ ์์ต๋๋ค., - ๊ฐ์ ์๊ฐ | ์ธํ๋ฐ...
www.inflearn.com
'๐๏ธ Spring > AOP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[AOP] ์ด๋๋ฐ์ด์ค์ ์ข ๋ฅ (0) | 2022.08.03 |
---|---|
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (10) - target (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (9) - this (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (8) - bean (0) | 2022.08.02 |
[AOP] AOP ํฌ์ธํธ์ปท ํํ์ (7) - @args (0) | 2022.08.02 |