日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

使用springaop技术面向切面编程

發布時間:2024/4/13 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用springaop技术面向切面编程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
手寫Spring的事務框架,SpringAOP的技術你們用過沒有,Spring事務分為兩種,一種叫編程式事務,一種叫聲明式事務,我講一下SpringAOP的技術怎么用,項目jar包依賴信息,因為我們會用到數據源,要做事務處理,第一步把所有的jar包copy進來 <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.learn</groupId><artifactId>demo</artifactId><version>0.0.1-SNAPSHOT</version><dependencies><!-- https://mvnrepository.com/artifact/javassist/javassist --><dependency><groupId>javassist</groupId><artifactId>javassist</artifactId><version>3.12.1.GA</version></dependency><!-- 引入Spring-AOP等相關Jar --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>3.0.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>3.0.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>3.0.6.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>3.0.6.RELEASE</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.6.1</version></dependency><dependency><groupId>aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.5.3</version></dependency><dependency><groupId>cglib</groupId><artifactId>cglib</artifactId><version>2.1_2</version></dependency><!-- https://mvnrepository.com/artifact/com.mchange/c3p0 --><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.2</version></dependency><!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.37</version></dependency></dependencies></project> 是簡單的搭建一個Spring的環境,事務,AOP,因為我們待會會用到的,然后在這個地方我們就來做個操作,給他簡單的用一下Spring的AOP,有兩種實現方式,在SpringAOP的技術里面,一種叫做注解版本,還有一種是XML版本,我告訴你們,我一般是用注解版本的,很多去用xml版本的,為什么呢,因為你們以后會學一個SpringBoot的,你們以后盡量不要寫xml,因為你們發現用SpringBoot的時候,你根本就不寫xml了,全都是自動化的,全部都是注解版本的,所以我們講一下,xml版本我相信,在今后幾年當中,都會淘汰的,通過注解方式替代xml方式,今天我主要講注解版本,不去講xml版本了,你們可以自己去看看,我就不說了,那怎么去用呢,這個用法就比較簡單,大家想一下AOP的幾個點,然后我再去講一下代碼如何去整合,然后在這里給大家說一下 package com.learn.aop;import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.After; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component;/*** 做一個日志的處理* 這個類干嘛的呢* 其實就是切面類* 把我們重復的代碼全部放在AOP里面去* 這個代碼怎么寫* 首先記住這里加一個注解* @Apect表示這是一個切面類了* 然后放在容器里面去的@Component* * @author Leon.Sun**/ @Component @Aspect public class AogLog {/*** 在這里我們怎么去做處理呢* 首先這里有幾個方法一定要認真聽一下* SpringAOP里面有幾個通知* 第一個叫前置通知* 還有一個叫后置通知* 還又叫運行通知* 還有叫異常通知* 環繞通知* 我一個個講* * 這個通知我們就叫做前置通知* * 前置通知到底是干嘛目的* 你要寫一個表達式* 切入點的表達式* 這是我要給你們說一下* 切入點是啥意思* 假如你要攔截哪些方法* "execution(* com.learn.service.UserService.add(..))"* 你們看一下是什么意思啊* 這個表達式是做什么目的的* 表示我會去攔截com.learn.service.UserService這個類的add的方法* 我會在這個方法之前做一個攔截* 這個方法叫前置通知* */@Before("execution(* com.learn.service.UserService.add(..))")public void before() {/*** 在方法之前執行* */System.out.println("前置通知 在方法之前執行...");}/*** 我們在這里可以寫一個后置通知* 這個叫后置通知* 后置通知里我要怎么去寫呢* 這個我們怎么寫* 后置通知 在方法運行后執行* "execution(* com.learn.service.UserService.add(..))"* 我把這個表達式也copy過來*/@After("execution(* com.learn.service.UserService.add(..))")public void after() {/*** 在方法后執行*/System.out.println("后置通知 在方法之后執行...");}/*** 我依次類推* 運行通知* 首先這個通知是干嘛用的* 就是方法運行的時候就有這個通知*/@AfterReturning("execution(* com.learn.service.UserService.add(..))")public void returning() {System.out.println("運行通知");}/*** 這個表示在方法異常的情況下會有異常通知的* 大家不要小看異常通知* 為什么Spring事務為什么會失效呢* 就是我沒有注意異常* 我待會會細說的* * */@AfterThrowing("execution(* com.learn.service.UserService.add(..))")public void afterThrowing() {System.out.println("異常通知");}/*** 這個也是我們會經常用的環繞通知* 環繞通知里面是怎么寫的呢* 環繞通知 在方法之前和之后處理事情* ProceedingJoinPoint傳進來* 這個方法怎么用的呢* 就好比他在實際調用你的add方法* * 其實你們可以把表達式抽取出來* 我先這樣寫* 你們可以把表達式封裝成一個* 這也是可以的* * * @param proceedingJoinPoint* @throws Throwable*/@Around("execution(* com.learn.service.UserService.add(..))")public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{/*** 調用方法之前執行*/System.out.println("環繞通知 調用方法之前執行");/*** 這里有一個方法* 代理調用方法 注意點: 如果調用方法拋出溢出不會執行后面代碼* 相當于invoke* 這個方法非常核心* 你們使用Spring事務的時候為什么會失效呢* 如果沒有拋出這個異常* 如果你的調用方法拋出異常* 假設你拋出異常的情況下* 他就會怎么樣進行處理呢* 不會執行后面的代碼* 這是什么意思啊* 比如代理調用方法的時候* 假設去調用add方法的時候* 如果add方法里面突然報了一個錯* 他就不會往后面繼續執行的* 這是我要給你們說的* 所以你們使用事務的時候不要去try* 一定要拋出去* 拋的話會導致什么問題呢* 事務提交到數據庫里面去了* 你這樣會回滾的* 那肯定不好*/proceedingJoinPoint.proceed();/*** 調用方法之后執行*/System.out.println("環繞通知 調用方法之后執行");} } <?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:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 這里表示掃包范圍 因為我們是使用注解的,--><context:component-scan base-package="com.learn"></context:component-scan><!-- 這里表示開啟事務的注解 你如果想要事務的話,你必須開啟一個事務注解,--><aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 開啟事物注解 --><!-- 1. 數據源對象: C3P0連接池 --><bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"></property><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test"></property><property name="user" value="root"></property><property name="password" value="root"></property></bean><!-- 2. JdbcTemplate工具類實例 --><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><property name="dataSource" ref="dataSource"></property></bean><!-- 3.配置事務 --><bean id="dataSourceTransactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"></property></bean></beans> package com.learn.service.impl;import org.springframework.stereotype.Service;import com.learn.service.UserService;/*** 加上注解之后* @author Leon.Sun**/ @Service public class UserServiceImpl implements UserService {public void add() {try {int i = 10 /0;System.out.println("################往數據庫添加數據#################");} catch (Exception e) {}}} package com.learn.service;public interface UserService {public void add(); } package com.learn.test;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.learn.service.UserService;/*** 我們看一下AOP能不能成功* @author Leon.Sun**/ public class Test001 {public static void main(String[] args) {/*** new一下ClassPathXmlApplicationContext* 表示讀取到我們的spring.xml配置文件* */ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");/*** 這樣拿到我們的user接口* 把它強轉一下* */UserService userService = (UserService) applicationContext.getBean("userServiceImpl");/*** 前置通知* 環繞通知之前* 往數據庫里添加代碼* 后置通知* 運行通知* 環繞通知之后* * 異常通知現在有沒有運行過* 為什么* 因為我的方法沒有拋異常* 怎么可能運行我的異常通知* 我在add方法里面寫一個 int i = 10 /0* 寫完之后我們看一下效果* 是不是報錯了* 異常通知* 你們看一下環繞通知之后有沒有再運行* 環繞通知之后就會打印這段代碼* 有沒有執行* 因為它報錯了* 只要你調用的方法報錯的情況下* 他不會執行的* 這邊我就給你演示一個錯誤* * 比如我把它try一下* 這個時候環繞通知之后的代碼會不會執行* 環繞通知之后會不會執行* 會還是不會* 這肯定會* 因為他沒有把異常拋出來* 肯定是會的* 環繞方法調用之前和環繞方法調用之后* 這個時候就把注解版的事務講完了* 還有xml方式我就不去講了* * * */userService.add();}}//前置通知 在方法之前執行... //環繞通知 調用方法之前執行 //################往數據庫添加數據################# //后置通知 在方法之后執行... //運行通知 //環繞通知 調用方法之后執行//前置通知 在方法之前執行... //Exception in thread "main" java.lang.ArithmeticException: / by zero // at com.learn.service.impl.UserServiceImpl.add(UserServiceImpl.java:16) // at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) // at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) //環繞通知 調用方法之前執行 //后置通知 在方法之后執行... //異常通知 <aop:aspectj-autoproxy></aop:aspectj-autoproxy> 開啟事物注解權限 @Aspect 指定一個類為切面類 @Pointcut("execution(* com.itmayiedu.service.UserService.add(..))") 指定切入點表達式 @Before("pointCut_()") 前置通知: 目標方法之前執行 @After("pointCut_()") 后置通知:目標方法之后執行(始終執行) @AfterReturning("pointCut_()") 返回后通知: 執行方法結束前執行(異常不執行) @AfterThrowing("pointCut_()") 異常通知: 出現異常時候執行 @Around("pointCut_()") 環繞通知: 環繞目標方法執行 XML方式實現AOPXml實現aop編程:1) 引入jar文件 【aop 相關jar, 4個】2) 引入aop名稱空間3)aop 配置* 配置切面類 (重復執行代碼形成的類)* aop配置攔截哪些方法 / 攔截到方法后應用通知代碼 <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- dao 實例 --><bean id="userService" class="com.learn.service.UserService"></bean><!-- 切面類 --><bean id="aop" class="com.learn.aop.AopLog"></bean><!-- Aop配置 --><aop:config><!-- 定義一個切入點表達式: 攔截哪些方法 --><aop:pointcut expression="execution(* com.learn.service.UserService.*(..))"id="pt" /><!-- 切面 --><aop:aspect ref="aop"><!-- 環繞通知 --><aop:around method="around" pointcut-ref="pt" /><!-- 前置通知: 在目標方法調用前執行 --><aop:before method="begin" pointcut-ref="pt" /><!-- 后置通知: --><aop:after method="after" pointcut-ref="pt" /><!-- 返回后通知 --><aop:after-returning method="afterReturning"pointcut-ref="pt" /><!-- 異常通知 --><aop:after-throwing method="afterThrowing"pointcut-ref="pt" /></aop:aspect></aop:config></beans>

?

總結

以上是生活随笔為你收集整理的使用springaop技术面向切面编程的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。