@AspectJ 스타일에 대한 논의에서 언급했듯이, 명명 된 pointcuts를 사용하면 코드의 가독성을 크게 향상시킬 수 있습니다.
method속성은 advice의 body를을 제공하는 메소드 (doAccessCheck)를 식별합니다. 이 메소드는 어드바이스가 포함 된 aspect 요소에 의해 참조 된 bean에서 정의되어야합니다. 데이터 액세스 작업이 실행되기 전에 (pointcut 표현식과 일치하는 메소드 실행 join point), aspect bean에 대한 doAccessCheck메소드가 호출됩니다.
After Returning Advice
Returning advice는 일치하는 메소드 실행이 정상적으로 완료 될 때 실행됩니다. before advice와 같은 방법으로 <aop:aspect>내부에 선언됩니다. 다음 예제에서는 이를 선언하는 방법을 보여줍니다.
마지막 advice는 around advice 입니다. around advice는 매치 메소드 실행을 '둘러싼'다. 메소드가 실행되기 전과 후에 모두 작업을 수행 할 수있는 기회를 가지며 메소드가 실제로 실행될시기, 방법 및 방법을 결정합니다. around advice는 스레드 안전 방식으로 메서드 실행 전후의 상태를 공유하는 데 자주 사용됩니다 (예 : 타이머 시작 및 중지). 항상 귀하의 요구 사항을 충족시키는 가장 강력한 형태의 advice를 사용하십시오. before advice가 그 일을 할 수 있다면 around advice를 사용하지 마십시오.
메소드 실행 전 후 익셉션 모두 처리 가능!
aop:around 요소를 사용하여 around advice를 선언 할 수 있습니다. advice 메소드의 첫 번째 매개 변수는 ProceedingJoinPoint유형이어야 합니다. advice body에서 ProceedingJoinPoint에서 proceed()를 호출하면 기본 메서드가 실행됩니다. proceed메서드는 Object[]를 사용하여 호출 할 수도 있습니다. 배열의 값은 진행될 때 메서드 실행에 대한 인수로 사용됩니다. 호출 시 Object[]로 proceed를 호출하는 것에 대해 알아보려면 Around Advice를 참고하십시오. 다음 예는 XML에서 around advice를 선언하는 방법을 보여줍니다.
proceed()를 기준으로 위의 소스는 before, 아래의 소스는 afterThrowing 로 구분 지어질 수 있다.
proceed() 의 리턴 값은 Object 이다. 이는 Aspect 로 연결된 Original Method 의 리턴 값을 받을 수 있다. ( 형 변환 )
스키마 기반 선언 스타일은 @AspectJ 지원에 대해 설명한 것과 동일한 방식으로 완전히 입력 된 조언을 지원합니다. 즉, 포인트 메서드 매개 변수를 이름으로 advice 메서드 매개 변수에 일치시킵니다. 자세한 내용은 Advice Parameters를 참조하십시오. 앞서 설명한 검색 방법에 의존하지 않고 advice 메소드에 대한 인수 이름을 명시 적으로 지정하려면 argNames속성과 동일한 방식으로 처리되는 advice 요소의 arg-names 속성을 사용하면됩니다 조언 주석에서 (Determining Argument Names에 설명 된대로). 다음 예제에서는 XML에서 인수 이름을 지정하는 방법을 보여줍니다.
<aop:before
pointcut="com.xyz.lib.Pointcuts.anyPublicMethod() and @annotation(auditable)"
method="audit"
arg-names="auditable"/>
arg-names 속성은 매개 변수 이름의 쉼표로 구분 된 목록을 허용합니다.
XSD 기반 접근 방식의 약간 더 관여 된 다음 예는 강하게 유형화 된 여러 매개 변수와 함께 사용되는 몇 가지 around advice를 보여줍니다.
package x.y.service;
public interface PersonService {
Person getPerson(String personName, int age);
}
public class DefaultFooService implements FooService {
public Person getPerson(String name, int age) {
return new Person(name, age);
}
}
다음은 aspect 입니다. profile(..) 메소드는 강력한 형식의 매개 변수를 여러 개 허용하며, 그 중 첫 번째는 메소드 호출을 진행하는 데 사용되는 조인 포인트입니다. 이 매개 변수가 있으면 다음 예제와 같이 profile(..)이 aroundadvice로 사용된다는 표시입니다.
package x.y;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.util.StopWatch;
public class SimpleProfiler {
public Object profile(ProceedingJoinPoint call, String name, int age) throws Throwable {
StopWatch clock = new StopWatch("Profiling for '" + name + "' and '" + age + "'");
try {
clock.start(call.toShortString());
return call.proceed();
} finally {
clock.stop();
System.out.println(clock.prettyPrint());
}
}
}
마지막으로, 다음 예제 XML 구성은 특정 조인 포인트에 대한 선행 조언의 실행에 영향을줍니다.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- this is the object that will be proxied by Spring's AOP infrastructure -->
<bean id="personService" class="x.y.service.DefaultPersonService"/>
<!-- this is the actual advice itself -->
<bean id="profiler" class="x.y.SimpleProfiler"/>
<aop:config>
<aop:aspect ref="profiler">
<aop:pointcut id="theExecutionOfSomePersonServiceMethod"
expression="execution(* x.y.service.PersonService.getPerson(String,int))
and args(name, age)"/>
<aop:around pointcut-ref="theExecutionOfSomePersonServiceMethod"
method="profile"/>
</aop:aspect>
</aop:config>
</beans>
다음의 driver 스크립트를 참고하십시오.
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import x.y.service.PersonService;
public final class Boot {
public static void main(final String[] args) throws Exception {
BeanFactory ctx = new ClassPathXmlApplicationContext("x/y/plain.xml");
PersonService person = (PersonService) ctx.getBean("personService");
person.getPerson("Pengo", 12);
}
}
Boot 클래스를 사용하면 표준 출력에서 다음과 비슷한 결과를 얻을 수 있습니다.
StopWatch 'Profiling for 'Pengo' and '12'': running time (millis) = 0
-----------------------------------------
ms % Task name
-----------------------------------------
00000 ? execution(getFoo)
Advice Ordering
여러 advice가 동일한 조인 포인트 (실행 메소드)에서 실행되어야하는 경우 주문 규칙은 Advice Ordering에 설명되어 있습니다. aspect 간의 우선 순위는 aspect를 뒷받침하는 bean에 Order주석을 추가하거나 bean이 Ordered 인터페이스를 구현하도록함으로써 결정됩니다.