Весенние уведомления AOP разделены на пять категорий:
Перед советом: выполнить перед точкой соединения. Предварительный просмотр не повлияет на выполнение точки подключения, если здесь не будет выброшено исключение.
Нормальное уведомление о возврате [после возвращения советов]: выполнить после завершения нормального выполнения точки соединения. Если исключение брошено точкой подключения, оно не будет выполнено.
Уведомление о возврате исключений [после броска советов]: выполнить после того, как исключение брошено точкой подключения.
Уведомление о возврате [после (наконец) совета]: После завершения выполнения содержимое уведомления о возврате будет выполнено, будет ли оно завершено нормально или исключение.
Вокруг совета: вокруг совета окружает точку соединения, например, до и после вызова метода. Это самый мощный тип уведомления, который может настроить некоторые операции до и после вызовов методов.
Окружающее уведомление также должно решить, продолжать ли продолжить обработку точки соединения (вызов метода процесса выполнения) или прерывания выполнения.
Далее мы протестируем пять типов уведомлений, написав примерную программу:
Определить интерфейс
пакет com.chenqa.springaop.example.service; public interface bankservice { / *** Смоделированное банковское трансфер* @param из учетной записи* @param к учетной записи* @param atumper atmer* @return* / public boolean transfer (строка, строка, двойная учетная запись);};};};};Напишите классы реализации
Пакет com.chenqa.springaop.example.service.impl; import com.chenqa.springaop.example.service.bankservice; открытый класс Bcmbankserviceimpl внедряет банкервис {public boolean (строка, строка, двойная учетная запись) {account usmervice {throw newladargex insecteex insememe effervecteex effervecteex effervecteex eformex everservecteex eformex eformex presscepteex ‘if informer usmemex insterlar Юань "); } System.out.println (form+"Transfer to"+To+"банковский счет"+account+"yuan"); вернуть ложь; }}Измените файл конфигурации пружины и добавьте следующее:
<!-BankService Bean-> <Bean Id = "Bankservice"/> <!-раздел-> <bean id = "myaspect"/> <!-AOP Configuration-> <AOP: config> <aop: аспект ref = "myAspect"> <aop: pointcut Expression = "exepring (*com.chenqa.spring.exple. id="pointcut"/> <aop:before method="before" pointcut-ref="pointcut"/> <aop:after method="after" pointcut-ref="pointcut"/> <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/> <aop: axe method = "ray" pointcut-ref = "pointcut"/> </aop: аспект> </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, а затем вывод после выполнения:
Из результатов теста можно видеть, что порядок выполнения пяти уведомлений состоит из:
Предварительная отмену → Уведомление о объеме → Уведомление о возврате/исключение нормальное возвращение → Уведомление о возврате, вы можете выполнить несколько раз для просмотра.
Случай 1: Метод перехватывается только одним аспектом
Когда метод перехвачен только одним аспектом, в каком порядке выполняются различные советы в этом аспекте? Пожалуйста, смотрите:
Добавить класс точки
Эта точка используется для перехвата всех методов во всех классах под тестовым пакетом.
Пакет Test; Import org.aspectj.lang.annotation.pointcut; открытый класс pointcuts {@pointcut (value = "into (test.*)") public void aopdemo () {}}Добавить аспект класса
Совет в этом классе будет использовать точку выше. Пожалуйста, обратитесь к атрибуту значения каждого совета при его использовании.
Пакет тест; импорт org.aspectj.lang.joinpoint; import org.aspectj.lang.proudeingjoinpoint; import org.aspectj.lang.annotation.*; импорт org.springframework.stereotype.component;@component@aspect opect apect1 {@before (value.pointcut. До (JOINPOINT JOINPOINT) {System.out.println ("[аспект1] до совета"); } @Around (value = "test.pointcuts.aopdemo ()") public void вокруг (restingjoinpoint pjp) бросает throwable {System.out.println ("[аспект1] вокруг совета 1"); pjp.proecd (); System.out.println ("[аспект1] вокруг совета2"); } @AfterReturning (value = "test.pointcuts.aopdemo ()") public void после повторного повторного повторного обмена (JoinPoint joinPoint) {System.out.println ("[Aspist1] после повторного повторного совета"); } @AfterThroving (value = "test.pointCuts.aopdemo ()") public void после прохождения (joinpoint joinpoint) {System.out.println ("[Asposive1] после прохождения совета"); } @After (value = "test.pointcuts.aopdemo ()") public void после (joinpoint joinpoint) {system.out.println ("[аспект1] последующий совет"); } @After (value = "test.pointcuts.aopdemo ()") public void после (joinpoint joinpoint) {System.out.println ("[Aspist1] после консультирования"); }}Добавить тестовый контроллер
Добавьте контроллер для тестирования. В этом контроллере есть только один метод, но он будет обрабатывать по -разному в соответствии со значениями параметров: один - это нормально возвращать объект, а другой - бросить исключение (потому что мы хотим проверить советы @afterthrowing)
Тест пакета; импорт test.exception.testexception; import org.springframework.http.httpstatus; import org.springframework.web.bind.annotation.*; @restcontroller @requestmapp = "/test", method = requestMethod.get) тест на публичный результат (@RequestParam Boolean ThrowException) {// case 1 if (throwexception) {System.out.println ("бросить исключение"); бросить новое TestException ("Mock A Exception Server Exception"); } // case 2 system.out.println ("test ok"); вернуть новый результат () {{this.setid (111); this.SetName («Вытекает на результат»); }}; } public Static Class Result {private int id; Приватное название строки; public int getId () {return id; } public void setId (int id) {this.id = id; } public String getName () {return name; } public void setName (string name) {this.name = name; }}}Проверьте нормальную ситуацию
Введите следующий URL непосредственно в браузер и введите: http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false 1
Мы увидим результат вывода:
[Аспект1] вокруг совета 1 [аспект1] перед советом ОК [Аспект1] вокруг совета2 [Аспект1] после совета [Аспект1] после повторного совета
Тестовые исключения
Непосредственно введите следующий URL в браузере и нажмите Enter: http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true 1
Мы увидим результат вывода:
[Аспект1] вокруг совета 1 [аспект1] перед посоветованием.
в заключение
Когда метод перехвачен только одним классом аспекта, советы внутри класса аспекта будут выполнены в следующем порядке:
Нормальная ситуация:
Исключение:
Случай 2: тот же метод перехватывается несколькими аспектами классов
Вот пример, который перехвачен двумя аспектами.
В некоторых случаях для двух разных классов аспекта, независимо от того, использует ли их советы одинаковую точку или разные точки, это может привести к перехвату одного и того же метода, который будет перехвачен несколькими классами аспектов. Итак, в этом случае, в каком порядке выполняются советы в этих нескольких аспектах? Пожалуйста, смотрите:
Класс Pointcut остается неизменным
Добавить новый класс аспекта
Тест пакета; импорт org.aspectj.lang.joinpoint; import org.aspectj.lang.proudeingjoinpoint; import org.aspectj.lang.annotation.*; импорт org.springframework.stepolype.component;@component@aspect opect aspect2 {@before (value.point.pointcut До (JOINPOINT JOINPOINT) {System.out.println ("[аспект2] до совета"); } @Around (value = "test.pointcuts.aopdemo ()") public void вокруг (restingjoinpoint pjp) бросает {system.out.println ("[аспект2] вокруг совета 1"); pjp.proecd (); System.out.println ("[аспект2] вокруг совета2"); } @AfterReturning (value = "test.pointcuts.aopdemo ()") public void после повторного повторного повторения (joinpoint joinpoint) {System.out.println ("[Aspist2] после повторного повторного совета"); } @AfterThroving (value = "test.pointCuts.aopdemo ()") public void после послепрощения (JoinPoint joinPoint) {System.out.println ("[Aspose2] после прохождения совета"); } @After (value = "test.pointcuts.aopdemo ()") public void после (joinpoint joinpoint) {system.out.println ("[аспект2] последующий совет"); } @After (value = "test.pointcuts.aopdemo ()") public void после (joinpoint joinpoint) {system.out.println ("[аспект2] после консультирования"); }}Тестовый контроллер также не изменился
Все еще используйте контроллер выше. Но теперь как аспект1, так и аспект 2 перехватывают методы в контроллере.
Продолжайте проверять ниже!
Проверьте нормальную ситуацию
Введите следующий URL непосредственно в браузер и введите: http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=false 1
Мы увидим результат вывода:
[Аспект2] вокруг совета 1 [Аспект2] до совета [Аспект1] вокруг совета 1 [Аспект1] До совета ОК [Аспект1] вокруг совета2 [Аспект1] после совета [Аспект1] после повторного совета [Аспект2] вокруг совета2 [аспект2] после повторного обращения к совету
Но в настоящее время я не могу заключить, что аспект2 определенно выполнен до аспекта1.
Не верите в это? Вы перезагружаете сервер и попробуете еще раз, возможно, вы увидите следующие результаты выполнения:
[Аспект1] Вокруг совета 1 [Аспект1] До совета [Аспект2] вокруг совета 1 [Аспект 2] до совета ОК [Аспект2] вокруг совета2 [Аспект2] после совета [Аспект2] после повторного совета [Аспект1] вокруг совета 2 [аспект1] после повторного обращения к совету
То есть в этом случае порядок выполнения аспекта1 и аспекта2 неизвестен. Так как это решить? Не спешите, решение будет дано ниже.
Тестовые исключения
Непосредственно введите следующий URL в браузере и нажмите Enter: http://192.168.142.8:7070/aoptest/v1/aop/test?throwException=true 1
Мы увидим результат вывода:
[Аспект2] Вокруг совета 1 [Аспект2] до совета [Аспект1] вокруг совета 1 [Аспект1], прежде чем посоветовать исключение [Аспект1] после броска консультаций [Аспект2] после броска консультаций
Точно так же, если вы перезагрузите сервер, а затем протестируете его снова, вы можете увидеть следующие результаты:
[Аспект1] Вокруг совета 1 [Аспект1] До совета [Аспект2] вокруг совета 1 [Аспект2], прежде чем посоветовать исключение [Аспект2] после проведения совета [Аспект1] после прохождения совета
То есть так же, порядок выполнения аспекта1 и аспекта2 также не определяется в исключительных обстоятельствах.
Итак, в случае 2, как вы указываете порядок выполнения каждого аспекта?
Есть два метода:
Независимо от того, какой метод используется, тем меньше аспект, тем больше он выполняется в первую очередь.
Например, мы добавляем аннотации @Order для APSECT1 и Aspose2 соответственно, следующим образом:
@Order (5)@component@AspizePublic Class Aspose1 {// ...}@Order (6)@Component@AspizePublic Class Aspose2 {// ...} После этой модификации можно гарантировать, что в любом случае советы в аспекте 1 всегда выполняются до совета в аспекте2. Как показано на рисунке ниже:
Примечание
Если определены два идентичных совета по одной и той же точке (например, два @before), то порядок выполнения этих двух советов не может быть определен, даже если вы добавите аннотацию @Order к этим двум советам, он не будет работать. Помните это.
Для совета @Around, независимо от того, имеет ли он возвращаемое значение или нет, он должен вызвать pjp.proceedceed () внутри метода; В противном случае интерфейс в контроллере не будет выполнен, что также приведет к тому, что советы @before не будут запускаться. Например, мы предполагаем, что при нормальных обстоятельствах порядок выполнения является «Amposial2 -> Apsect1 -> Controller». Если мы удалим pjp.proceedceed (); В @Around в аспекте1, тогда выход, который мы видим:
[Аспект 2] вокруг совета 1 [аспект 2] до совета [аспект1] вокруг совета 1 [аспект1] вокруг совета2 [аспект1] после совета [аспект1] после повторного совета [аспект 2] вокруг совета2 [аспект2] после повторного представления совета
Из результатов мы можем обнаружить, что интерфейс в контроллере не был выполнен, и @beforeadvice в аспекте1 также не выполнялся.
Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.