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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

AOP的理解以及实现

發布時間:2023/12/15 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 AOP的理解以及实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

AOP

一、AOP概念

? AOP即面向切面編程。我們先來理解下為什么會需要AOP?

? 如果在編程時多個類中有重復出現的代碼,那么我們就應該考慮將這些重復代碼抽取出來定義成一個抽象類,這種情況我們稱為縱向抽取。但是如果這些重復的代碼是分散在各個業務邏輯中的,比如事務控制中有大量的try-catch-finally代碼,這些重復代碼嵌套在主要的業務邏輯代碼中,我們用上面的方法就抽取不了,這時我們就可以通過橫向切割的方式,把這些重復代碼抽取到一個獨立的模塊中,在以后調用對應的業務邏輯方法時,又將這些重復代碼橫向切入進去。從而達到讓業務邏輯類保持最初的單純。

? 我們用一個例子來說明。如下圖:是一個對數據庫進行操作的步驟:

? 1、連接數據庫

? 2、執行SQL語句

? 3、是否有異常,有就回滾事務,沒有就提交事務

? 4、關閉資源

? 我們可以看到每次對數據庫進行一次操作后,都會有如下的步驟,其中的1-3-4步驟都是重復的,而作為開發人員我們每次真正需要關心的只是步驟2的SQL語句執行(因為這在每個操作中是不一樣的),而對于其他的我們則可以交由AOP去實現這些步驟,我們只需通過注解或者XML的配置來告訴AOP我們需要在那些類下的哪些方法中切入這些重復的代碼,這樣在編寫代碼時我們就只需關注核心邏輯代碼,而在運行時AOP會對我們需要加入重復代碼的方法進行攔截,并將這些重復代碼切入進去。

? 值得一提的是AOP并不是Spring框架特有的,Spring只是支持AOP編程的框架之一,且SpringAOP是一種基于方法攔截的AOP,也就是說Spring只能支持方法攔截的AOP。

二、AOP術語

1、切面(Aspect):切面由切點和增加(需要切入的代碼、方法也叫通知)組成,它既包括了橫切邏輯的定義,也包括了連接點的定義,SpringAOP就是將切面所定義的橫切邏輯織入到切面所制定的連接點中。

2、增強、通知(Advice):是切面的方法,也就是一段需要切入到目標對象的代碼。根據他在代理對象真實方法調用前、后和邏輯分為以下幾種:

? 前置通知(before):在真實對象方法調用前執行

? 后置通知(after):在真實對象方法調用后執行

? 返回通知(afterReturning):在執行業務代碼后無異常執行

? 異常通知(afterThrowing):在執行業務代碼發送異常后執行

? 環繞通知(around):最強的通知,可以取代原對象方法。但使用也較復雜

3、切點(Pointcut):告訴SpringAOP在什么時候啟動攔截并織入對應的流程中。

4、連接點(join point):連接點對應的是一個具體的方法,比如通過切點的正則表達式去判斷那些方法是連接點。

5、織入(Weaving):織入就是將增強添加到目標具體連接點上的過程。

三、基于純注解的AOP實現:

主要步驟:

? 1、創建業務邏輯接口,實現接口

? 2、創建切面,切面中包含切點和需要切入的方法

? 3、創建AOP配置類,啟動Aspectj自動代理、掃描bean、生成切面類

? 4、測試AOP

1、創建一個接口 里面的方法就是我們的連接點,也就是我們需要攔截這個方法并將通知織入

package com.test.aop;public interface Student {void getName(); }

2、創建這個接口的實現

package com.test.aop;import org.springframework.stereotype.Component;@Component public class StudentImpl implements Student {@Overridepublic void getName() {System.out.println("我叫唐鵬,我自豪");} }

3、創建切面,并定義切點和邏輯方法

package com.test.aop;import org.aspectj.lang.annotation.*;@Aspect public class TestAspect {@Pointcut("execution(* com.test.aop.*.getName(..))")public void pointCut(){}@Before("pointCut()")public void before(){System.out.println("=====前置:小么小么小二郎喲,背著書包上學堂咯");}@After("pointCut()")public void after(){System.out.println("=====后置:終于放學了!");}@AfterReturning("pointCut()")public void afterReturning(){System.out.println("=====返回:今天真呀真高興");}@AfterThrowing("pointCut()")public void afterThrowing(){System.out.println("=====異常:oh 我考試考了0分,可不高興");} }

4、創建AOP配置類

package com.test.aop;import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy;//啟用Aspectj自動代理 @EnableAspectJAutoProxy //配置掃描的包 這是掃描bean的配置 @ComponentScan("com.test") public class AopConfig {//生成切面類,自定義的類里面設置了切點@Beanpublic TestAspect getTestAspect(){return new TestAspect();} }

5、測試AOP

package com.test.aop;import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class TestMain {public static void main(String[] args) {//因為是采用注解所以使用AnnotationConfigAopApplicationContext來實現ApplicationContext ac = new AnnotationConfigApplicationContext(AopConfig.class);Student tp = (Student) ac.getBean("studentImpl");tp.getName();} }

6、結果打印

=====前置:小么小么小二郎喲,背著書包上學堂咯 我叫唐鵬,我自豪 =====后置:終于放學了! =====返回:今天真呀真高興

四、基于純XML開發AOP的方式:

基本步驟:

? 1、同樣先創建接口和接口實現類

? 2、創建切面類和切入方法,因為是采用XML的方式,所以這里不需要指明他是個切面類,也不需要指定切入方法對應的切入點。,只需要生成對應的方法和方法代碼即可。

? 3、創建spirng配置文件

? 4、測試

1、接口和實現同上,這里就不在給出。(注意如果是在不同包下使用相同類名,注意包的引用)

2、編寫切面類

package com.test.aopXml;public class TestAspect {public void before(){System.out.println("=====XML前置:小么小么小二郎喲,背著書包上學堂咯");}public void after(){System.out.println("=====XML后置:終于放學了!");}public void afterReturning(){System.out.println("=====XML返回:今天真呀真高興");}public void afterThrowing(){System.out.println("=====XML異常:oh 我考試考了0分,可不高興");}}

3、spring的配置文件applicationContext.xml 注意放在resources源碼文件下面

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><bean id ="student" class="com.test.aopXml.StudentImpl"/><bean id ="testAspect" class="com.test.aopXml.TestAspect"/><!--aop配置--><aop:config ><!--定義切面,和切點配置--><aop:aspect ref="testAspect"><!--定義需要重復使用的切點--><aop:pointcut id="pointCut" expression="execution(* com.test.aopXml.StudentImpl.*(..))"/><!--定義切點,method是指切面類中對應的方法名--><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:aspect></aop:config></beans>

4、測試

package com.test.aopXml;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMain {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");Student student = (Student) ac.getBean("student");student.getName();} }

5、測試結果

=====XML前置:小么小么小二郎喲,背著書包上學堂咯 我叫唐鵬,我自豪 =====XML后置:終于放學了! =====XML返回:今天真呀真高興

五、注解和XML混合開發的方式

注解和XML混合使用:切點信息定義在切面類,xml中只需要開啟對aspectj自動代理和配置掃描就好

步驟如下:

? 1、同樣給出接口和實現類

? 2、編寫切面類,切面類需要加入容器,讓ioc管理

? 3、配置applicationContext1.xml文件

? 4、測試

1、接口和實現同上

2、編寫切面類,這里切面類加上了@Component注解 而在使用純注解時是沒有加上的

package com.test.aop;import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component;@Component @Aspect public class TestAspect {@Pointcut("execution(* com.test.aop.*.getName(..))")public void pointCut(){}@Before("pointCut()")public void before(){System.out.println("=====混合前置:小么小么小二郎喲,背著書包上學堂咯");}@After("pointCut()")public void after(){System.out.println("=====混合后置:終于放學了!");}@AfterReturning("pointCut()")public void afterReturning(){System.out.println("=====混合返回:今天真呀真高興");}@AfterThrowing("pointCut()")public void afterThrowing(){System.out.println("=====混合異常:oh 我考試考了0分,可不高興");} }

3、applicationContext1.xml文件

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:context="http://www.springframework.org/schema/context"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!--此配置是為了讓spring知道我們配置了切面,讓他掃描bean的時候注意到切面類--><aop:aspectj-autoproxy/><!--掃描bean--><context:component-scan base-package="com.test.aop"/></beans>

4、測試

package com.test.aop;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public class TestMain {public static void main(String[] args) {ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext1.xml");Student student = (Student) ac.getBean("studentImpl");student.getName();} }

5、測試結果

=====混合前置:小么小么小二郎喲,背著書包上學堂咯 我叫唐鵬,我自豪 =====混合后置:終于放學了! =====混合返回:今天真呀真高興

總結

以上是生活随笔為你收集整理的AOP的理解以及实现的全部內容,希望文章能夠幫你解決所遇到的問題。

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