Spring AOP 알림은 5 가지 범주로 나뉩니다.
조언 전에 : 연결 지점 앞에서 실행하십시오. 예외가 발생하지 않는 한 미리보기는 연결 지점의 실행에 영향을 미치지 않습니다.
정상 반환 알림 [반환 조언 후] : 연결 지점의 정상 실행 후 실행이 완료됩니다. 연결 지점에서 예외가 발생하면 실행되지 않습니다.
예외 반환 알림 [조언을 던진 후] : 연결 지점에서 예외가 발생한 후 실행합니다.
반환 알림 [후 (마지막으로) 조언] : 실행이 완료된 후 반환 알림의 내용은 정상적으로 완료되었는지 여부에 관계없이 실행됩니다.
조언 주변 : 조언 주변은 메소드 호출 전후와 같은 연결 지점을 둘러싸고 있습니다. 이것은 메소드 호출 전후의 일부 작업을 사용자 정의 할 수있는 가장 강력한 알림 유형입니다.
주변 알림은 또한 조인 포인트를 계속 처리 할 것인지 (ProceedingHoinPoint의 프로세스 방법 호출) 또는 인터럽트 실행 여부를 결정해야합니다.
다음으로 샘플 프로그램을 작성하여 5 가지 알림 유형을 테스트합니다.
인터페이스를 정의하십시오
package com.chenqa.springaop.example.service; public interface bankservice { / *** 시뮬레이션 은행 송금* @param에서 계정* @param에서 계정으로* @param 계정 이체 금액* @return* / public boolean 송금 (문자열 양식, 이중 계정);}구현 클래스를 작성하십시오
packet com.chenqa.springaop.example.service.impl; import com.chenqa.springaop.example.service.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice.bankservice. backservice {public boolean 송금 (문자열, 문자열 to, double account) {(계정 <100) {new new new legal angummentexemention이 될 수 없음). 위안 "); } system.out.println (form+"송금"+to+"은행 계정"+계정+"yuan"); 거짓을 반환합니다. }}스프링 구성 파일을 수정하고 다음을 추가하십시오.
<!-bankservice bean-> <bean id = "bankservice"/> <!-섹션-> <bean id = "myaspect"/> <!-aop configuration-> <aop : config> <aop : "myaspect"> <aop : pointcut expression = "com.chenqa.springaop.explice.service.service.service. id = "pointcut"/> <aop : 이전 메소드 = "전"pointcut-ref = "pointcut"/> <aop : after method = "pointcut-ref ="pointcut "/> <aop : after returning method ="af PointCut-Ref = "PointCut"/> <aop : 주변 메소드 = "주변"PointCut-Ref = "PointCut"/> </aop : Aspect> </aop : config>
테스트 프로그램 작성
ApplicationContext Context = New ClassPathXmlApplicationContext ( "Spring-Aop.xml"); Bankservice Bankservice = Context.getBean ( "Bankservice", Bankservice.class); Bankservice.Transfer ( "Zhang San", "Li Si", 200);
실행 후 출력 :
테스트 프로그램에서 200을 50으로 변경 한 다음 실행 후 출력 :
테스트 결과에서 5 개의 알림의 실행 순서가 다음과 같습니다.
사전 확인 → 서라운드 알림 → 정상 반환 알림/예외 반환 알림 → 반환 알림을 여러 번 수행 할 수 있습니다.
사례 1 : 메소드는 한 종자 클래스에 의해서만 가로 채 웁니다.
방법이 하나의 측면에 의해서만 가로 채는 경우,이 측면의 다른 조언은 어떤 순서대로 실행됩니까? 참조하십시오 :
Pointcut 클래스를 추가하십시오
이 점수는 테스트 패키지의 모든 클래스의 모든 메소드를 가로 채는 데 사용됩니다.
패키지 테스트; import org.aspectj.lang.annotation.pointcut; public class pointcut {@pointcut (value = "내 (test.*)") public void aopdemo () {}}측면 클래스를 추가하십시오
이 수업의 조언은 위의 점수를 사용합니다. 사용할 때 각 조언의 값 속성을 참조하십시오.
패키지 테스트; import org.aspectj.lang.joinpoint; import org.aspectj.lang.proceedingjoinpoint; import org.aspectj.lang.annotation.*; import org.spramework.stereotyp.component;@component@problic class1 {value = problecuts.aopdemo ()). {System.out.println ( "[[Aspect1]] 조언 전"); } @around (value = "test.pointcuts.aopdemo ()") 공개 void (proceedingjoinpoint pjp)는 던질 수있는 {system.out.println ( "[Sateg1]]의 조언 1"); pjp.proceed (); System.out.println ( "[Aspect1] Around Advice2"); } @AfTerReTurning (value = "test.pointcuts.aopdemo ()") 공개 void After -ReTurning (joinpoint joinpoint) {System.out.println ( "[Sage1] 후 조언 이후"); } @AfterThrowing (value = "test.pointcuts.aopdemo ()") public void apterrowing (joinpoint joinpoint) {system.out.println ( "[[[[[a Sector1]]] After rowing Advice]); } @after (value = "test.pointcuts.aopdemo ()") public void apter (joinpoint joinpoint) {system.out.println ( "[[[[[[[[publice -point. } @after (value = "test.pointcuts.aopdemo ()") public void apter (joinpoint joinpoint) {system.out.println ( "[[[[[a Sected. }}테스트 컨트롤러를 추가하십시오
테스트를 위해 컨트롤러를 추가하십시오. 이 컨트롤러에는 하나의 메소드가 있지만 매개 변수 값에 따라 다르게 처리됩니다. 하나는 객체를 정상적으로 반환하는 것이고, 다른 하나는 예외를 던지는 것입니다 (@afterthrowing 조언을 테스트하기 때문에).
패키지 테스트; import test.exception.testexception; import org.springframework.http.httpstatus; import org.springframework.web.bind.annotation.*; @restcontroller @requestmapping (value = "/aop") public classe aoptestcontroller {@responsestscath (httponsustus) @ = "/test", method = requestmethod.get) 공개 결과 테스트 (@requestparam boolean strashexception) {// case 1 if (strowException) {system.out.println ( "예외를 던지기"); 새로운 testException을 던지십시오 ( "서버 예외 조롱"); } // case 2 system.out.println ( "테스트 확인"); 새 결과를 반환합니다 () {{this.setid (111); this.setName ( "mock a renate"); }}; } 공개 정적 클래스 결과 {private int id; 개인 문자열 이름; public int getid () {return id; } public void setid (int id) {this.id = id; } public String getName () {return name; } public void setName (문자열 이름) {this.name = 이름; }}}정상적인 상황을 테스트하십시오
브라우저에 다음 URL을 직접 입력하고 http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false 1을 입력하십시오.
출력 결과를 볼 수 있습니다.
[Aspect1] 조언 1 [Aspect1] 전 조언 OK OK OK [ASTERE1] 조언 후 조언 2 [ASTOM1] 조언 후 조언 후 조언이 끝난 후 [Aspect1]
테스트 예외
브라우저에 다음 URL을 직접 입력하고 Enter를 누르십시오 : http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true 1
출력 결과를 볼 수 있습니다.
[Aspect1] Advicethrow 이전의 조언 1 [Aspect1] Advicethrow [Aspect1] 후 조언 이후 [Aspect1] After rowing Advice.
결론적으로
메소드가 하나의 측면 클래스에 의해서만 가로 채는 경우, Aspect 클래스 내부의 조언은 다음 순서로 실행됩니다.
정상적인 상황 :
예외:
사례 2 : 동일한 방법이 여러 종자 클래스에 의해 가로 채 웁니다.
다음은 두 가지 측면 클래스로 가로 채는 예입니다.
경우에 따라, 두 가지 다른 측면 클래스의 경우, 조언이 동일한 지점 컷 또는 다른 포인트 컷을 사용하는지 여부에 관계없이 동일한 방법이 여러 측면 클래스에 의해 가로 채게 될 수 있습니다. 이 경우, 이러한 여러 종자 클래스의 조언은 어떤 순서로 실행됩니까? 참조하십시오 :
포인트 컷 클래스는 변경되지 않았습니다
새로운 측면 클래스를 추가하십시오
패키지 테스트; import org.aspectj.lang.joinpoint; import org.aspectj.lang.proceedingjoinpoint; import org.aspectj.lang.annotation.*; import org.spramework.stereotyp.component;@component@affublic class2 {@bepoblefore (value = pointcuts.aopdemo () " {System.out.println ( "[Aspect2] 조언 전"); } @around (value = "test.pointcuts.aopdemo ()") 공개 void (proceedingjoinpoint pjp)는 던질 수있는 {system.out.println ( "[Sateg2] 주변 조언 1"); pjp.proceed (); System.out.println ( "[Sater2] Around Advice2"); } @AfTerReTurning (value = "test.pointcuts.aopdemo ()") 공개 void After -ReTurning (joinpoint joinpoint) {System.out.println ( "[[[[[afure -joince. } @AfterThrowing (value = "test.pointcuts.aopdemo ()") public void apterrowing (joinpoint joinpoint) {system.out.println ( "[[[[[a Sector2] After2] After) } @after (value = "test.pointcuts.aopdemo ()") public void apter (joinpoint joinpoint) {system.out.println ( "[[[[[[[public rowing. } @after (value = "test.pointcuts.aopdemo ()") public void apter (joinpoint joinpoint) {system.out.println ( "[[[[[[public ritonefpoint)))"; }}테스트 컨트롤러도 변경되지 않았습니다
위의 컨트롤러를 사용하십시오. 그러나 이제는 측면 1과 종면 2가 컨트롤러의 메소드를 가로 채 웁니다.
아래에서 계속 테스트하십시오!
정상적인 상황을 테스트하십시오
브라우저에 다음 URL을 직접 입력하고 http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false 1을 입력하십시오.
출력 결과를 볼 수 있습니다.
[Aspect2] 조언 1 [Aspect2] 전의 조언 1 [Aspect1] [Aspect1]에 대한 조언 1 [Aspect1] 전 조언 OK [SASPOL1] ANBOCTE 2 [ASTOME1] 조언 후 조언을 겪은 후 조언 [ASTERE2] 조언을 겪은 후 조언 2 [ASTER2] 후 조언을 시작합니다.
그러나 현재, 나는 Species 1 이전에 SACENT2가 확실히 실행된다고 결론을 내릴 수 없다.
믿지 않습니까? 서버를 다시 시작하고 다시 시도하면 다음 실행 결과가 표시 될 수 있습니다.
[Aspect1] [Aspoction 1 [Aspect2] 전 조용한 조언 1 [Aspect2] [Aspect2]에 대한 조언 1 [Aspect2] 전 조언 OK [Aspect2] As
즉,이 경우 SAPING1 및 SACENT2의 실행 순서는 알려져 있지 않습니다. 그래서 그것을 해결하는 방법? 서두르지 않으면 솔루션은 아래에 제공됩니다.
테스트 예외
브라우저에 다음 URL을 직접 입력하고 Enter를 누르십시오 : http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true 1
출력 결과를 볼 수 있습니다.
[Aspect2] 조언 1 [Aspect2] 전 조언 전의 조언 1 [Aspect1] [Aspect1]에 대한 조언 1 [Aspect1]은 조언을 던진 후 예외 [Aspect1]을 맹세하기 전에 [Aspect1] 조언을 던진 후 [Aspect2]
마찬가지로 서버를 다시 시작한 다음 다시 테스트하면 다음 결과가 표시 될 수 있습니다.
[Aspect1] As
즉, 마찬가지로, Aspect1 및 Sagne의 실행 순서도 예외적 인 상황에서도 결정되지 않습니다.
따라서 사례 2에서 각 측면의 실행 순서를 어떻게 지정합니까?
두 가지 방법이 있습니다.
어떤 방법을 사용하든 측면이 작을수록 먼저 더 많이 실행됩니다.
예를 들어, 우리는 다음과 같이 APSECT1 및 SACENT2에 대한 @Order 주석을 각각 추가합니다.
@Order (5)@component@public class spect1 {// ...}@order (6)@component@public class sagne {// ...} 이 수정 후, Aspect1의 조언은 항상 Sage 2의 조언 전에 항상 실행되도록 보장 할 수 있습니다. 아래 그림과 같이 :
메모
동일한 포인트 컷에 대해 두 가지 동일한 조언이 정의되면 (예 : @before)가 정의 된 경우이 두 가지 조언에 @Order 주석을 추가 하더라도이 두 가지 조언의 실행 순서를 결정할 수 없습니다. 이것을 기억하십시오.
@around 조언의 경우 반환 값이 있는지 여부에 관계없이 메소드 내부에서 pjp.proceed ()를 호출해야합니다. 그렇지 않으면 컨트롤러의 인터페이스가 실행되지 않으므로 @Before 조언이 트리거되지 않습니다. 예를 들어, 정상적인 상황에서 실행 순서는 "Sagne2-> apsect1-> 컨트롤러"라고 가정합니다. pjp.proceed ()를 삭제하는 경우; @around의 SAPER1에서 우리가 보는 출력은 다음과 같습니다.
[Aspect2] 조언 1 [Aspect2] 전의 조언 1 [Aspect1] [Aspect1]에 대한 조언 1 [Aspect1]에 대한 조언 2 [Aspect1]에 대한 조언 2 [Aspect1] 후 조언을 시작한 후 조언 [Aspect2]에 대한 조언 2 [Aspect2] 후 조언이 시작됩니다.
결과에서 컨트롤러의 인터페이스가 실행되지 않았으며 Sater1의 @beforeadvice도 실행되지 않았다는 것을 알 수 있습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.