Spring 中的AOP的通知類型的示例(xml)

  • 2019 年 10 月 5 日
  • 筆記

版權聲明:本文為部落客原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/qq_37933685/article/details/81637432

個人部落格:https://suveng.github.io/blog/​​​​​​​

Spring 中的AOP的通知類型的示例

AOP中的通知類型(advice)一共有五中:

  1. around advice 環繞通知
  2. before advice 前置通知
  3. after advice 返回通知
  4. after-throwing advice 異常返回通知
  5. after-returning advice 正常返回通知

具體詳情請查看Spring的官方文檔:https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/core.html#aop-api-advice

那麼現在我們來搭建spring的環境。 你可以用很多中方式搭建spring的環境,可以自己導jar包,可以用maven,可以用gradle。 那麼我用的是maven。如果想下載spring的文檔和jar包,spring官網是下載不了的,需要去到ftp網址。 這裡提供網址:https://docs.spring.io/spring/docs/ 這裡面有spring每一個版本的jar 和docs 文檔

那麼我用maven,新建一個空的maven工程,然後吧依賴導進去,我這裡按照spring模組劃分依賴。

pom.xml

<?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>my.suveng</groupId>      <artifactId>springcoredemo</artifactId>      <version>1.0-SNAPSHOT</version>        <properties>          <org.springframework.version>5.0.8.RELEASE</org.springframework.version>      </properties>        <dependencies>          <!-- spring start -->            <!--spring core start-->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-beans</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-core</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-context</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-expression</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-context-support</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-context-indexer</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring core end-->            <!--spring aop start-->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-aop</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spirng aop end-->            <!--spring aspects start-->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-aspects</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring aspects end-->            <!--spring instrumentation start -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-instrument</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring instrumentation end-->            <!--spring messaging start -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-messaging</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring messaging end-->            <!--spring data access start -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-jdbc</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-orm</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-oxm</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-jms</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-tx</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring data access end-->            <!--spring web start -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-websocket</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-web</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-webmvc</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-webflux</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring web end -->            <!--spring test start -->          <dependency>              <groupId>org.springframework</groupId>              <artifactId>spring-test</artifactId>              <version>${org.springframework.version}</version>          </dependency>          <!--spring test end -->          <!-- spring end -->          <!--junit4-->          <dependency>              <groupId>junit</groupId>              <artifactId>junit</artifactId>              <version>4.12</version>          </dependency>          <!--end-->      </dependencies>  <build>      <resources>          <resource>              <directory>src/main/java</directory>              <includes>                  <include>**/*.xml</include>              </includes>          </resource>      </resources>  </build>    </project>

配置好spring環境後,需要準備一些類來做切點,這裡我才用哦面向介面,先建一個UserDao介面和一個實現類,然後將實現類交給spring去管理(使用註解方式)

UserDao.java

/**   * author: Veng Su   * email: [email protected]   * date: 2018/8/13 15:11   */  public interface UserDao {      public void say();  }

UserDaoImpl.java

/**   * author: Veng Su   * email: [email protected]   * date: 2018/8/13 15:12   */  @Component(value = "userDao")  public class UserDaoImpl implements UserDao {      public void say() {  //        int i=10/0;          System.out.println("hello ,suveng ");        }  }

這裡使用註解,需要用到包掃描註解。

例如:<context:component-scan base-package="spring.my.suveng"/>

到這裡切點已經準備好了,那麼切面類需要準備一下,也就是增強的內容。

這裡新建一個myAspect.java,把它交給spring管理

myAspect.java

/**   * author: Veng Su   * email: [email protected]   * date: 2018/8/13 15:25   */  @Component(value = "myAspect")  public class myAspect {      //before 切      public void beforeF(){          System.out.println("我是before");      }      //after 切      public void afterF(){          System.out.println("我是after");      }      //after_throwing 切      public void afterTF(){          System.out.println("我是after-throwing");      }      //after-returning 切      public void afterRF(){          System.out.println("我是after-returning");      }      //around 切 要把joinpoint給傳進來      public void aroundF(ProceedingJoinPoint joinPoint){          System.out.println("前around");          try {              joinPoint.proceed();          } catch (Throwable throwable) {              throwable.printStackTrace();          }          System.out.println("後 around");        }  }

既然切點和切面類已經準備好了,那麼可以開始用xml配置了。

beans.xml

<?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:context="http://www.springframework.org/schema/context"         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/context          http://www.springframework.org/schema/context/spring-context.xsd          http://www.springframework.org/schema/aop          http://www.springframework.org/schema/aop/spring-aop.xsd">        <context:component-scan base-package="spring.my.suveng"/>      <!-- 配置 AOP -->      <aop:config>            <!-- 配置切面 = 切入點 + 通知 -->          <aop:aspect ref="myAspect">                <!-- 配置切入點                  expression 表達式                  execution(想要切的方法寫到這裡)                  execution(訪問許可權 返回值類型 包路徑.方法名(參數))              -->              <!--前置通知-->              <aop:before method="beforeF" pointcut="execution(* *..*.*.say())"/>              <!--無論程式有沒有出錯,通知都會執行-->              <aop:after method="afterF" pointcut="execution(* *..*.*.say())"/>              <!--執行完後就執行通知,但拋異常或出現錯誤就不會執行通知-->              <aop:after-returning method="afterRF" pointcut="execution(* *..*.*.say())"/>              <!--只有拋異常的時候才會執行通知-->              <aop:after-throwing method="afterTF" pointcut="execution(* *..*.*.say())"/>              <!--無論程式有沒有出錯,環繞通知都會執行-->              <aop:around method="aroundF" pointcut="execution(* *..*.*.say())"/>              <!--<aop:around method="arround" pointcut="execution(* *..*.*.save())"/>-->              </aop:aspect>        </aop:config>  </beans>

到這裡,整個aop已經配置完成了,開始測試:

SpringTest.java

@RunWith(SpringJUnit4ClassRunner.class)  @ContextConfiguration("classpath:spring/config/beans.xml")  public class SpringTest {      @Resource(name = "userDao")      UserDao userDao;      @Test      public void testAop(){          userDao.say();      }  }

運行結果:

碼雲源碼鏈接

https://gitee.com/suwenguang/SpringFrameworkDemo

總結

這裡是綜合測試,讀者可以單個測試,把其他注釋掉,還可以在切點加入異常,比如除數為0的異常,看看異常會對切面類的造成什麼樣的影響。其實我做了這個測試,只是我不想貼出來。

使用註解配置aop可以看:

https://blog.csdn.net/qq_37933685/article/details/81673831

AOP的應用很廣泛,遠不止這麼簡單,這只是個示例,想知道更多配置aop的方法可以看https://www.yiibai.com/spring_aop/。也可以看spring 官方文檔https://docs.spring.io/spring/docs/5.0.8.RELEASE/spring-framework-reference/core.html#aop。加油