# 6.7 Advised 객체들 조작하기 by sh

## 6.7. Advised 객체들 조작하기

**AOP 프록시를 만들었더라도, `org.springframework.aop.framework.Advised` 인터페이스를 사용하여 이를 조작 할 수 있습니다. 모든 AOP 프록시는 구현된 다른 인터페이스와 상관없이 이 인터페이스로 캐스트 될 수 있습니다.** 이 인터페이스에는 다음과 같은 메서드가 포함됩니다.&#x20;

```java
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, 인터셉터 또는 factory에 추가된 다른 advice 유형에 대한 `Advisor`를 리턴합니다.** `Advisor`를 추가한 경우,이 색인에서 리턴 된 advisor가 추가한 오브젝트입니다. 인터셉터 나 다른 advice 타입을 추가했다면, Spring은 항상 `true`를 리턴하는 pointcut을 사용하여 advisor에서 이것을 감쌉니다. 따라서 `MethodInterceptor`를 추가하면 이 인덱스에 대해 리턴 된 권고자는 `MethodInterceptor`를 리턴하는 `DefaultPointcutAdvisor`와 모든 클래스 및 메소드와 일치하는 pointcut입니다.&#x20;

**`addAdvisor()` 메소드를 사용하여 `Advisor`를 추가 할 수 있습니다.** 일반적으로 포인트 컷과 advice를 가지고있는 advisor는 일반적인 advice인 `DefaultPointcutAdvisor`를 사용하는데, 이는 advice 나 포인트 컷과 함께 사용할 수있습니다.&#x20;

**기본적으로 프록시가 작성된 후에도 advisor나 인터셉터를 추가하거나 제거 할 수 있습니다.** 유일한 제한은 factory의 기존 프록시가 인터페이스 변경을 보지 못하는 것처럼 인트로덕션 advisor를 추가하거나 제거 할 수 없다는 것입니다. 이 문제를 피하기 위해 factory에서 새 프록시를 얻을 수 있습니다.

다음 예제에서는 AOP 프록시를 `Advised`인터페이스에 캐스팅하고 advice를 검사하고 조작하는 방법을 보여줍니다.

다음 예제에서는 AOP 프록시를 `Advised`인터페이스에 캐스팅하고 advice를 검사하고 조작하는 방법을 보여줍니다.&#x20;

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

// Add an advice like an interceptor without a pointcut
// Will match all proxied methods
// Can use for interceptors, before, after returning or throws advice
advised.addAdvice(new DebugInterceptor());

// Add selective advice using a pointcut
advised.addAdvisor(new DefaultPointcutAdvisor(mySpecialPointcut, myAdvice));

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

| 합법적인 사용 사례는 있지만, 프로덕션 환경의 비즈니스 개체에 대한 advice를 수정하는 것이 좋습니다. 그러나 개발 (예 : 테스트)에는 매우 유용 할 수 있습니다. 테스트 코드를 인터셉터 또는 다른 advice 형태로 추가하여 테스트할 메소드 호출 내부로 들어가는 것이 때로는 매우 유용하다는 것을 발견했습니다. (예를 들어, advice는 롤백을 위해 트랜잭션을 표시하기 전에 데이터베이스가 올바르게 업데이트되었는지 SQL을 실행하여 해당 메소드에 대해 생성 된 트랜잭션 내부로 들어갈 수 있습니다.) |
| -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

**프록시 작성 방법에 따라 보통 `frozen`플래그를 설정할 수 있습니다. 이 경우 `Advised`** **`isFrozen()` 메소드는 `true`를 리턴하고 추가 또는 제거를 통해 advice를 수정하려는 시도는 `AopConfigException`을 초래합니다.** advised 객체의 상태를 고정시키는 기능은 경우에 따라 유용합니다 (예 : 보안 인터셉터를 제거하는 코드 호출을 방지하는 것).&#x20;

{% hint style="info" %}
Proxy 설정이 frozen되면, 더 이상 설정을 변경할 수 없다.
{% endhint %}
