Preface
aop in annotation mode needs several new annotations
1.@Aspect// indicates that this is a faceted class 2. @Pointcut ("execution (* com.cong.service.AccountService Impl. *(.))")// pointcut expression private void accountPointcut(){} 3. @Before (value = accountPointcut())// Pre-notification annotation, the parentheses of accountPointcut() cannot be removed Similarly, there are AfterReturning,AfterThrowing,Around 4. Also add a sentence in the configuration file to tell spring to turn on annotation aop support <! - Tell spring to turn on support for annotation aop - >. <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
1. Create maven projects and add dependencies
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.cong</groupId> <artifactId>spring_aop_annotation</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.2.RELEASE</version> </dependency> <!-- aop --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> </dependencies> </project>
2. Create the com.cong.pojo.Account class in the java directory, create objects through annotations, inject data, and add it to the ioc container
package com.cong.pojo; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component//Injection into ioc In containers public class Account { @Value("1") private int id; @Value("cong") private String name; @Value("100") private float money; @Override public String toString() { return "Account{" + "id=" + id + ", name='" + name + '\'' + ", money=" + money + '}'; } }
3. Create the com.cong.service package in the java directory, and create interfaces and classes
package com.cong.service; import com.cong.pojo.Account; public interface AccountService { void saveAccount(Account account); } package com.cong.service; import com.cong.pojo.Account; import org.springframework.stereotype.Service; @Service("accountService") public class AccountServiceImpl implements AccountService { @Override public void saveAccount(Account account) { System.out.println("save account..." + account.toString()); // int i = 1/0; } }
4. Create a com.cong.utils.MyTransaction notification class in the java directory
Comment out the comments surrounding the notification first
package com.cong.utils; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component// @Aspect//Indicates that this is a tangent class public class MyTransaction { @Pointcut("execution(* com.cong.service.AccountServiceImpl.*(..))")//Pointcut expression private void accountPointcut(){} //Before advice @Before(value = "accountPointcut()")//Pre-notification annotations public void beforeTransaction(){ System.out.println("Before advice MyTransaction In the class beforeTransaction Method executed..."); } //after returning advise @AfterReturning("execution(* com.cong.service.AccountServiceImpl.*(..))")//If no pointcut expression is configured public void afterReturningTransaction(){ System.out.println("after returning advise MyTransaction In the class afterReturningTransaction Method executed..."); } //Exception Notification @AfterThrowing("accountPointcut()") public void afterThrowingTransaction(){ System.out.println("Exception Notification MyTransaction In the class afterThrowingTransaction Method executed..."); } //Final Notice @After("accountPointcut()") public void afterTransaction(){ System.out.println("Final Notice MyTransaction In the class afterTransaction Method executed..."); } //Around Advice //@Around("accountPointcut()") public Object aroundTransaction(ProceedingJoinPoint proceedingJoinPoint){ Object res = null; try { Object args [] = proceedingJoinPoint.getArgs(); beforeTransaction(); proceedingJoinPoint.proceed(args); afterReturningTransaction(); return res; }catch (Throwable throwable){ afterThrowingTransaction(); return new RuntimeException(throwable); }finally { afterTransaction(); } } }
5. Create a bean.xml file in the resources directory
<?xml version="1.0" encoding="UTF-8"?> <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" xmlns:context="http://www.springframework.org/schema/context" 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 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- To configure spring Packets to be scanned --> <context:component-scan base-package="com.cong"></context:component-scan> <!-- inform spring,Open Notes aop Support --> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
6. Create test classes under test, java directory
import com.cong.pojo.Account; import com.cong.service.AccountService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AopAnnotationTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); AccountService accountService = (AccountService)context.getBean("accountService"); Account account = (Account)context.getBean("account"); accountService.saveAccount(account); } }
7. Operational results are somewhat different from what we imagine.
The order of post-notification and exception notification is obviously different.
This is the problem that spring annotation-based aop does have sequential calls, so the choice in actual development should be carefully considered.
Information: Loading XML bean definitions from class path resource [bean.xml]
The beforeTransaction method in the MyTransaction class is notified in advance that it executes...
save account...Account{id=1, name='cong', money=100.0}
Eventually notify the MyTransaction class that the afterTransaction method has executed...
The after Returning Transaction method in the MyTransaction class is notified to execute the ___________.
8. Annotate the pre-notification, post-notification, exception notification and final notification, and cancel the annotation surrounding the notification.
//Before advice //@Before(value = "accountPointcut()")//Pre-notification annotations public void beforeTransaction(){ System.out.println("Before advice MyTransaction In the class beforeTransaction Method executed..."); } //after returning advise //@AfterReturning("execution(* com.cong.service.AccountServiceImpl.*(..))")//If no pointcut expression is configured public void afterReturningTransaction(){ System.out.println("after returning advise MyTransaction In the class afterReturningTransaction Method executed..."); } //Exception Notification //@AfterThrowing("accountPointcut()") public void afterThrowingTransaction(){ System.out.println("Exception Notification MyTransaction In the class afterThrowingTransaction Method executed..."); } //Final Notice //@After("accountPointcut()") public void afterTransaction(){ System.out.println("Final Notice MyTransaction In the class afterTransaction Method executed..."); } //Around Advice @Around("accountPointcut()") public Object aroundTransaction(ProceedingJoinPoint proceedingJoinPoint){ Object res = null; try { Object args [] = proceedingJoinPoint.getArgs(); beforeTransaction(); proceedingJoinPoint.proceed(args); afterReturningTransaction(); return res; }catch (Throwable throwable){ afterThrowingTransaction(); return new RuntimeException(throwable); }finally { afterTransaction(); } }
9. Execute it again so that the order of calls is not a problem. After all, this is all our own code.
Information: Loading XML bean definitions from class path resource [bean.xml] The beforeTransaction method in the MyTransaction class is notified in advance that it executes... save account...Account{id=1, name='cong', money=100.0} The after Returning Transaction method in the MyTransaction class is notified to execute the ___________. Eventually notify the MyTransaction class that the afterTransaction method has executed...