๐ก ๊น์ํ๋์ ์คํ๋ง ํต์ฌ ์๋ฆฌ ๊ณ ๊ธํธ ๊ฐ์๋ฅผ ๋ฃ๊ณ ์ ๋ฆฌํ ๋ด์ฉ์
๋๋ค.
ํฌ์ธํธ์ปท ์ง์์
์ ์คํํธJ๋ ํฌ์ธํธ์ปท์ ํธ๋ฆฌํ๊ฒ ํํํ๊ธฐ ์ํ ํน๋ณํ ํํ์์ ์ ๊ณตํ๋ค.
์) @Pointcut("execution(* hello.aop.order..*(..))")
ํฌ์ธํธ์ปท ํํ์์ AspectJ pointcut expression ์ฆ ์ ์คํํธJ๊ฐ ์ ๊ณตํ๋ ํฌ์ธํธ์ปท ํํ์์ ์ค์ฌ์ ๋งํ๋ ๊ฒ์ด๋ค.
ํฌ์ธํธ์ปท ์ง์์
ํฌ์ธํธ์ปท ํํ์์ execution ๊ฐ์ ํฌ์ธํธ์ปท ์ง์์(Pointcut Designator)๋ก ์์ํ๋ค. ์ค์ฌ์ PCD๋ผ ํ๋ค.
ํฌ์ธํธ์ปท ์ง์์์ ์ข ๋ฅ
- execution: ๋ฉ์๋ ์คํ ์กฐ์ธ ํฌ์ธํธ๋ฅผ ๋งค์นญํ๋ค. ์คํ๋ง AOP์์ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๊ณ , ๊ธฐ๋ฅ๋ ๋ณต์กํ๋ค.
- within: ํน์ ํ์ ๋ด์ ์กฐ์ธ ํฌ์ธํธ๋ฅผ ๋งค์นญํ๋ค
- args: ์ธ์๊ฐ ์ฃผ์ด์ง ํ์ ์ ์ธ์คํด์ค์ธ ์กฐ์ธ ํฌ์ธํธ
- this: ์คํ๋ง ๋น ๊ฐ์ฒด(์คํ๋ง AOP ํ๋ก์)๋ฅผ ๋์์ผ๋ก ํ๋ ์กฐ์ธ ํฌ์ธํธ
- target: Target ๊ฐ์ฒด(์คํ๋ง AOP ํ๋ก์๊ฐ ๊ฐ๋ฆฌํค๋ ์ค์ ๋์)๋ฅผ ๋์์ผ๋ก ํ๋ ์กฐ์ธ ํฌ์ธํธ
- @target: ์คํ ๊ฐ์ฒด์ ํด๋์ค์ ์ฃผ์ด์ง ํ์ ์ ์ ๋ ธํ ์ด์ ์ด ์๋ ์กฐ์ธ ํฌ์ธํธ
- @within: ์ฃผ์ด์ง ์ ๋ ธํ ์ด์ ์ด ์๋ ํ์ ๋ด ์กฐ์ธ ํฌ์ธํธ
- @annotation: ๋ฉ์๋๊ฐ ์ฃผ์ด์ง ์ ๋ ธํ ์ด์ ์ ๊ฐ์ง๊ณ ์๋ ์กฐ์ธ ํฌ์ธํธ๋ฅผ ๋งค์นญ
- @args: ์ ๋ฌ๋ ์ค์ ์ธ์์ ๋ฐํ์ ํ์ ์ด ์ฃผ์ด์ง ํ์ ์ ์ ๋ ธํ ์ด์ ์ ๊ฐ๋ ์กฐ์ธ ํฌ์ธํธ
- bean: ์คํ๋ง ์ ์ฉ ํฌ์ธํธ์ปท ์ง์์, ๋น์ ์ด๋ฆ์ผ๋ก ํฌ์ธํธ์ปท์ ์ง์ ํ๋ค.
ClassAop
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAop {
}
MethodAop
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodAop {
String value();
}
MemberServiceImpl
@ClassAop
@Component
public class MemberServiceImpl implements MemberService {
@Override
@MethodAop("test value")
public String hello(String param) {
return "ok";
}
public String internal(String param) {
return "ok";
}
}
ExecutionTest
@Slf4j
public class ExecutionTest {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
Method helloMethod;
@BeforeEach
public void init() throws NoSuchMethodException {
helloMethod = MemberServiceImpl.class.getMethod("hello", String.class);
}
@Test
void printMethod() {
//public java.lang.String hello.aop.member.MemberServiceImpl.hello(java.lang.String)
log.info("helloMethod={}", helloMethod);
}
}
AspectJExpressionPointcut์ด ๋ฐ๋ก ํฌ์ธํธ์ปท ํํ์์ ์ฒ๋ฆฌํด์ฃผ๋ ํด๋์ค๋ค.
์ฌ๊ธฐ์ ํฌ์ธํธ์ปท ํํ์์ ์ง์ ํ๋ฉด ๋๋ค.
AspectJExpressionPointcut๋ ์์์ Pointcut ์ธํฐํ์ด์ค๋ฅผ ๊ฐ์ง๋ค.
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)throws-pattern?)
execution(์ ๊ทผ์ ์ด์? ๋ฐํํ์
์ ์ธํ์
?๋ฉ์๋์ด๋ฆ(ํ๋ผ๋ฏธํฐ) ์์ธ?)
- ๋ฉ์๋ ์คํ ์กฐ์ธ ํฌ์ธํธ๋ฅผ ๋งค์นญํ๋ค.
- ?๋ ์๋ตํ ์ ์๋ค.
- * ๊ฐ์ ํจํด์ ์ง์ ํ ์ ์๋ค.
exactMatch(๊ฐ์ฅ ์ ํํ ํฌ์ธํธ์ปท)
@Test
void exactMatch() {
//public java.lang.String hello.aop.member.MemberServiceImpl.hello(java.lang.String)
pointcut.setExpression("execution(public String hello.aop.member.MemberServiceImpl.hello(String))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
MemberServiceImpl.hello(String) ๋ฉ์๋์ ๊ฐ์ฅ ์ ํํ๊ฒ ๋ชจ๋ ๋ด์ฉ์ด ๋งค์นญ๋๋ ํํ์์ด๋ค.
AspectJExpressionPointcut์ pointcut.setExpression์ ํตํด์ ํฌ์ธํธ์ปท ํํ์์ ์ ์ฉํ ์ ์๋ค.
pointcut.matches(๋ฉ์๋, ๋์ ํด๋์ค)๋ฅผ ์คํํ๋ฉด ์ง์ ํ ํฌ์ธํธ์ปท ํํ์์ ๋งค์นญ ์ฌ๋ถ๋ฅผ true, false๋ก ๋ฐํํ๋ค.
๋งค์นญ ์กฐ๊ฑด
- ์ ๊ทผ์ ์ด์?: public
- ๋ฐํํ์ : String
- ์ ์ธํ์ ?: hello.aop.member.MemberServiceImpl
- ๋ฉ์๋์ด๋ฆ: hello
- ํ๋ผ๋ฏธํฐ: (String)
- ์์ธ?: ์๋ต
MemberServiceImpl.hello(String) ๋ฉ์๋์ ํฌ์ธํธ์ปท ํํ์์ ๋ชจ๋ ๋ด์ฉ์ด ์ ํํ๊ฒ ์ผ์นํ๋ค.
๋ฐ๋ผ์ true๋ฅผ ๋ฐํํ๋ค.
๊ฐ์ฅ ๋ง์ด ์๋ตํ ํฌ์ธํธ์ปท
@Test
void allMatch() {
pointcut.setExpression("execution(* *(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}โ
๋งค์นญ ์กฐ๊ฑด
- ์ ๊ทผ์ ์ด์?: ์๋ต
- ๋ฐํํ์ : *
- ์ ์ธํ์ ?: ์๋ต
- ๋ฉ์๋์ด๋ฆ: *
- ํ๋ผ๋ฏธํฐ: (..)
- ์์ธ?: ์์
*์ ์๋ฌด ๊ฐ์ด ๋ค์ด์๋ ๋๋ค๋ ๋ป์ด๋ค.
ํ๋ผ๋ฏธํฐ์์ .. ์ ํ๋ผ๋ฏธํฐ์ ํ์ ๊ณผ ํ๋ผ๋ฏธํฐ ์๊ฐ ์๊ด์๋ค๋ ๋ป์ด๋ค.
๋ฉ์๋ ์ด๋ฆ ๋งค์นญ ๊ด๋ จ ํฌ์ธํธ์ปท
@Test
void nameMatch() {
pointcut.setExpression("execution(* hello(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void nameMatchStar1() {
pointcut.setExpression("execution(* hel*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void nameMatchStar2() {
pointcut.setExpression("execution(* *el*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void nameMatchFalse() {
pointcut.setExpression("execution(* nono(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isFalse();
}
ํจํค์ง ๋งค์นญ ๊ด๋ จ ํฌ์ธํธ์ปท
@Test
void packageExactMatch1() {
pointcut.setExpression("execution(* hello.aop.member.MemberServiceImpl.hello(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void packageExactMatch2() {
pointcut.setExpression("execution(* hello.aop.member.*.*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void packageExactFalse() {
pointcut.setExpression("execution(* hello.aop.*.*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isFalse();
}
@Test
void packageMatchSubPackage1() {
pointcut.setExpression("execution(* hello.aop.member..*.*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}
@Test
void packageMatchSubPackage2() {
pointcut.setExpression("execution(* hello.aop..*.*(..))");
assertThat(pointcut.matches(helloMethod, MemberServiceImpl.class)).isTrue();
}โ
hello.aop.member.*(1).*(2)
- (1): ํ์
- (2): ๋ฉ์๋ ์ด๋ฆ
ํจํค์ง์์ . , .. ์ ์ฐจ์ด๋ฅผ ์ดํดํด์ผ ํ๋ค.
- . : ์ ํํ๊ฒ ํด๋น ์์น์ ํจํค์ง
- .. : ํด๋น ์์น์ ํจํค์ง์ ๊ทธ ํ์ ํจํค์ง๋ ํฌํจ
@target, @within
์ ์
- @target: ์คํ ๊ฐ์ฒด์ ํด๋์ค์ ์ฃผ์ด์ง ํ์ ์ ์ ๋ ธํ ์ด์ ์ด ์๋ ์กฐ์ธ ํฌ์ธํธ
- @within: ์ฃผ์ด์ง ์ ๋ ธํ ์ด์ ์ด ์๋ ํ์ ๋ด ์กฐ์ธ ํฌ์ธํธ
์ด๋ ต๊ฒ ์๊ฐํ ํ์์๋ค.
์ ๋ ธํ ์ด์ ์ ํ์ ์ ์ ์ฉํ๋ฉด ๋๋ค.
์ค๋ช
- @target, @within์ ๋ค์๊ณผ ๊ฐ์ด ํ์ ์ ์๋ ์ ๋ ธํ ์ด์ ์ผ๋ก AOP ์ ์ฉ ์ฌ๋ถ๋ฅผ ํ๋จํ๋ค.
- @target(hello.aop.member.annotation.ClassAop)
- @within(hello.aop.member.annotation.ClassAop)
@ClassAop
class Target{}
@target vs @within
@target์ ์ธ์คํด์ค์ ๋ชจ๋ ๋ฉ์๋๋ฅผ ์กฐ์ธ ํฌ์ธํธ๋ก ์ ์ฉํ๋ค.
@within์ ํด๋น ํ์ ๋ด์ ์๋ ๋ฉ์๋๋ง ์กฐ์ธ ํฌ์ธํธ๋ก ์ ์ฉํ๋ค.
์ฝ๊ฒ ์ด์ผ๊ธฐํด์ @target์ ๋ถ๋ชจ ํด๋์ค์ ๋ฉ์๋๊น์ง ์ด๋๋ฐ์ด์ค๋ฅผ ๋ค ์ ์ฉํ๊ณ , @within์ ์๊ธฐ ์์ ์ ํด๋์ค์ ์ ์๋ ๋ฉ์๋์๋ง ์ด๋๋ฐ์ด์ค๋ฅผ ์ ์ฉํ๋ค.

@target์ ๋ด๊ฐ ๊ฐ์ง๊ณ ์๋ ๋ชจ๋ ๋ฉ์๋(์์ ๋ฐ์ ํด๋์ค, ๊ตฌํํ ์ธํฐํ์ด์ค ๋ค์ ๋ฉ์๋)๊ฐ ๋์์ด ๋๋ค.
@within์ ๋ฑ ๋ํํ ๋ง ์ ์ฉ์ด ๋๋ค.
์ฃผ์
๋ค์ ํฌ์ธํธ์ปท ์ง์์๋ ๋จ๋ ์ผ๋ก ์ฌ์ฉํ๋ฉด ์๋๋ค. args, @args, @target
'Spring > AOP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์คํ๋ง AOP ๊ตฌํ (0) | 2024.11.13 |
---|---|
์คํ๋ง AOP ๊ฐ๋ (0) | 2024.11.12 |
@Aspect AOP (0) | 2024.11.12 |
๋น ํ์ฒ๋ฆฌ๊ธฐ (0) | 2024.11.12 |
ํฌ์ธํธ์ปท, ์ด๋๋ฐ์ด์ค, ์ด๋๋ฐ์ด์ (0) | 2024.11.11 |