Manipulating Advised Objects

2024. 11. 17. 13:06Spring Framework/Spring AOP APIs

AOP 프록시를 생성하는 방법에 관계없이, org.springframework.aop.framework.Advised 인터페이스를 사용하여 프록시를 조작할 수 있습니다. AOP 프록시는 구현한 다른 인터페이스에 관계없이 이 인터페이스로 캐스팅할 수 있습니다. 이 인터페이스에는 다음과 같은 메서드들이 포함되어 있습니다:

Advisor[] getAdvisors();

void addAdvice(Advice advice) throws AopConfigException;

void addAdvice(int pos, Advice advice) throws AopConfigException;

void addAdvisor(Advisor advisor) throws AopConfigException;

void addAdvisor(int pos, Advisor advisor) throws AopConfigException;

int indexOf(Advisor advisor);

boolean removeAdvisor(Advisor advisor) throws AopConfigException;

void removeAdvisor(int index) throws AopConfigException;

boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException;

boolean isFrozen();

getAdvisors() 메서드는 팩토리에 추가된 어드바이저, 인터셉터, 또는 다른 어드바이스 타입에 대한 Advisor 객체를 반환합니다. 만약 어드바이저를 추가했다면, 해당 인덱스에서 반환된 어드바이저는 추가한 객체입니다. 인터셉터나 다른 어드바이스 타입을 추가했다면, Spring은 이를 포인트컷이 항상 true를 반환하는 어드바이저로 감쌉니다. 예를 들어, MethodInterceptor를 추가한 경우, 해당 인덱스에서 반환된 어드바이저는 DefaultPointcutAdvisor이며, 이 어드바이저는 MethodInterceptor와 모든 클래스 및 메서드에 매칭되는 포인트컷을 반환합니다.

addAdvisor() 메서드는 어떤 어드바이저도 추가하는 데 사용할 수 있습니다. 일반적으로 포인트컷과 어드바이스를 보유하는 어드바이저는 DefaultPointcutAdvisor이며, 이는 어떤 어드바이스나 포인트컷과도 사용할 수 있습니다(도입(introductions) 제외).

기본적으로, 프록시가 생성된 후에도 어드바이저나 인터셉터를 추가하거나 제거할 수 있습니다. 단, 도입 어드바이저를 추가하거나 제거하는 것은 불가능한데, 이는 팩토리에서 생성된 기존 프록시가 인터페이스 변경을 반영하지 않기 때문입니다(이 문제를 피하려면 팩토리에서 새 프록시를 얻을 수 있습니다).

다음 예제는 AOP 프록시를 Advised 인터페이스로 캐스팅한 후, 그 어드바이스를 검사하고 조작하는 방법을 보여줍니다:

Advised advised = (Advised) myObject;
Advisor[] advisors = advised.getAdvisors();
int oldAdvisorCount = advisors.length;
System.out.println(oldAdvisorCount + " advisors");

// 포인트컷 없이 인터셉터와 같은 어드바이스 추가
// 모든 프록시된 메서드에 매칭됨
// 인터셉터, before, after returning, throws 어드바이스에 사용할 수 있음
advised.addAdvice(new DebugInterceptor());

// 포인트컷을 사용하여 선택적인 어드바이스 추가
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));

assertEquals("Added two advisors", oldAdvisorCount + 2, advised.getAdvisors().length);

프로덕션 환경에서 비즈니스 객체의 어드바이스를 수정하는 것이 바람직한지는 의문이지만, 분명히 정당한 사용 사례가 있을 수 있습니다. 그러나 개발 중(예: 테스트 시)에는 매우 유용할 수 있습니다. 메서드 호출을 테스트하기 위해 인터셉터나 다른 어드바이스 형태로 테스트 코드를 추가할 수 있는 기능은 매우 유용합니다. (예를 들어, 어드바이스가 해당 메서드에 대해 생성된 트랜잭션 내부에서 SQL을 실행하여 데이터베이스가 올바르게 업데이트되었는지 확인하고, 트랜잭션을 롤백하도록 설정할 수 있습니다.)

프록시를 생성한 방법에 따라, 일반적으로 frozen 플래그를 설정할 수 있습니다. 이 경우, Advised의 isFrozen() 메서드는 true를 반환하며, 어드바이스를 추가하거나 제거하려는 시도는 AopConfigException을 발생시킵니다. 어드바이스된 객체의 상태를 고정(freeze)하는 기능은 일부 경우(예: 호출 코드가 보안 인터셉터를 제거하지 못하도록 방지하는 경우)에 유용할 수 있습니다.

'Spring Framework > Spring AOP APIs' 카테고리의 다른 글

Spring AOP APIs  (0) 2024.12.02
Using the "auto-proxy" facility  (1) 2024.11.17
Creating AOP Proxies Programmatically with the ProxyFactory  (0) 2024.11.17
The Advisor API in Spring  (0) 2024.11.17
Advice API in Spring  (0) 2024.11.17