最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中的AOP操作你了解嗎

 更新時(shí)間:2022年02月14日 16:31:17   作者:溪午聞璐  
這篇文章主要為大家詳細(xì)介紹了Spring中的AOP操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助

一、AOP操作術(shù)語 

1. 連接點(diǎn)

類里面哪些方法可以被增強(qiáng),這些可以被增強(qiáng)的方法就稱為連接點(diǎn)。

2. 切入點(diǎn)

實(shí)際被真正增強(qiáng)的方法,稱為切入點(diǎn)。

3. 通知(增強(qiáng))

(1)實(shí)際增強(qiáng)的邏輯部分稱為通知(增強(qiáng))

(2)通知有如下多種類型,如下:

  • 前置通知
  • 后置通知
  • 環(huán)繞通知
  • 異常通知
  • 最終通知(finally)

4. 切面

切面是一個(gè)動(dòng)作,指的是將通知應(yīng)用到切入點(diǎn)的過程,就叫做切面。

二、AOP操作

Spring 框架一般都是基于 AspectJ 實(shí)現(xiàn) AOP 操作。AspectJ 不是 Spring 組成部分,而是獨(dú)立 AOP 框架,一般把 AspectJ 和 Spirng 框架一起使用,進(jìn)行 AOP 操作 。

基于AspectJ實(shí)現(xiàn)AOP操作有如下兩種方式:

  • 基于 xml 配置文件實(shí)現(xiàn) 
  • 基于注解方式實(shí)現(xiàn)(使用) 

2.1 切入點(diǎn)表達(dá)式

切入點(diǎn)表達(dá)式作用:知道對(duì)哪個(gè)類里面的哪個(gè)方法進(jìn)行增強(qiáng) ,語法結(jié)構(gòu)如下所示:

execution([權(quán)限修飾符] [返回類型] [類全路徑] [方法名稱]([參數(shù)列表]) 

如下圖所示: 

編寫切點(diǎn)示例如下

1. 如對(duì)com.wyf.spring5.Book類中的add進(jìn)行增強(qiáng),則切入點(diǎn)表達(dá)式如下:

execution(* com.wyf.spring5.Book.add(..))

2. 如對(duì)com.wyf.spring5.Book類中所有的方法增強(qiáng):

execution(* com.wyf.spring5.Book.*(..))

3. 如對(duì) com.wyf.spring5包中的所有類,類中的所有方法都進(jìn)行加強(qiáng)

execution(*  com.wyf.spring5.*.* (..)) 

2.2 AOP操作(AspectJ 注解方式)

 1) 首先我們創(chuàng)建一個(gè)類,并添加一個(gè)方法

/** * 被增強(qiáng)類 */public class User {    public void add(){        System.out.println("add*****");    }}/**
 * 被增強(qiáng)類
 */
public class User {
    public void add(){
        System.out.println("add*****");
    }
}

2)接著我們創(chuàng)建增強(qiáng)類(編寫增強(qiáng)邏輯) 

在增強(qiáng)類中創(chuàng)建方法,讓不同的方法代表不同的通知類型

/**
 * 增強(qiáng)類
 */
public class UserProxy {
    /**
     * 前置通知邏輯
     */
    public void before(){
        System.out.println("before*****");
    }
}

3)進(jìn)行通知的配置

在spring配置文件中,開啟注解掃描。(采用java配置類或xml配置文件實(shí)現(xiàn))

<?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="com.wyf.aopanno"></context:component-scan>    <!-- 開啟Aspect 生成代理對(duì)象 -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>    </beans><?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="com.wyf.aopanno"></context:component-scan>
    <!-- 開啟Aspect 生成代理對(duì)象 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
  • 使用注解創(chuàng)建User和UserProxy對(duì)象(類上面添加創(chuàng)建對(duì)象注解,此處為 @Component)
  • 在增強(qiáng)類上面添加注解@Aspect
/**
 * 被增強(qiáng)類
 */
@Component
public class User {
    public void add(){
        System.out.println("add*****");
    }
}
/**
 * 增強(qiáng)類
 */
@Component
@Aspect  //生成代理對(duì)象
public class UserProxy {
    /**
     * 前置通知邏輯
     */
    public void before(){
        System.out.println("before*****");
    }
}

在 spring 配置文件中開啟生成代理對(duì)象 

    <!-- 開啟Aspect 生成代理對(duì)象 -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

開啟Aspect生成代理對(duì)象,相當(dāng)掃描帶有@Aspect注解的類,并生成該對(duì)象的一個(gè)代理對(duì)象。

4)配置不同類型通知

在增強(qiáng)類的里面,在作為通知方法上面添加通知類型注解,使用切入點(diǎn)表達(dá)式配置。

/**
 * 增強(qiáng)類
 */
@Component
@Aspect  //生成代理對(duì)象
public class UserProxy {
    /**
     * 前置通知邏輯
     */
    //@Before注解表示其作為前置通知
    //切入點(diǎn)表達(dá)式指定該通知為哪個(gè)類的哪個(gè)方法進(jìn)行增強(qiáng)。
    @Before(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void before(){
        System.out.println("before*****");
    }
}

測(cè)試代碼如下:

    @Test
    public void TestAop(){
        //1. 加載spring 配置文件
        ApplicationContext context = new ClassPathXmlApplicationContext("beanAop1.xml");
        //得到對(duì)象
        User user = context.getBean("user",User.class);
        user.add();
    }

執(zhí)行結(jié)果:

前文只給出了前置通知@Before的代碼,下面給出所有5種通知的示例代碼,對(duì)上例的所有通知情況進(jìn)行補(bǔ)全。

/**
 * 增強(qiáng)類
 */
@Component
@Aspect  //生成代理對(duì)象
public class UserProxy {
    /**
     * 前置通知邏輯
     */
    //@Before注解表示其作為前置通知
    //切入點(diǎn)表達(dá)式指定該通知為哪個(gè)類的哪個(gè)方法進(jìn)行增強(qiáng)。
    @Before(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void before(){
        System.out.println("before*****");
    }
    /**
     * 后置通知(返回通知)
     */
    @AfterReturning(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void afterReturning(){
        System.out.println("afterReturning*****");
    }
    /**
     * 最終通知,有異常也會(huì)執(zhí)行
     */
    @After(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void after(){
        System.out.println("after*****");
    }
    /**
     * 異常通知
     */
    @AfterThrowing(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void afterthrowing(){
        System.out.println("afterthrowing*****");
    }
    /**
     * 環(huán)繞通知,在方法之前和之后均通知
     */
    @Around(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("環(huán)繞之前*****");
        //執(zhí)行被增強(qiáng)的方法
        proceedingJoinPoint.proceed();
        System.out.println("環(huán)繞之后*****");
    }

代碼執(zhí)行結(jié)果如下:

其中,after是在被增強(qiáng)方法之后執(zhí)行,而afterreturning是在方法返回值之后執(zhí)行。

2.3 相同切入點(diǎn)的抽取

在上例種,我們編寫了被增強(qiáng)方放的5種通知,分別為前置通知、后置通知、異常通知、最終通知以及環(huán)繞通知。我們?cè)诰帉懺鰪?qiáng)類時(shí),在通知注解中通過切入點(diǎn)表達(dá)式,指明了通知要對(duì)哪個(gè)類的哪個(gè)方法進(jìn)行增強(qiáng)。但是,我們會(huì)發(fā)現(xiàn),我們對(duì)同一方法進(jìn)行增強(qiáng)時(shí),其切入點(diǎn)表達(dá)式是相同的,為了避免重復(fù),我們可以相同切入點(diǎn)進(jìn)行抽取。

下例中,我們將相同切入點(diǎn)用@Pointcut進(jìn)行了抽取,代碼如下所示:

    //對(duì)相同切入點(diǎn)進(jìn)行抽取
    @Pointcut(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void pointdemo(){
    }

當(dāng)我們?cè)谄渌胤揭迷撉腥朦c(diǎn)表達(dá)式時(shí),直接用其方法名稱就可以。

如下所示:

@Component
@Aspect
@Order(2)
public class PersonProxy {
    //前置通知
    @Before(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void before(){
        System.out.println("Person Before****");
    }
}

2.4 多個(gè)增強(qiáng)類對(duì)同一個(gè)方法進(jìn)行增強(qiáng),設(shè)置增強(qiáng)類優(yōu)先級(jí) 

假如我們現(xiàn)在又有一個(gè)增強(qiáng)類,其中也包含一個(gè)before()方法,也對(duì)被增強(qiáng)類User的add()方法進(jìn)行前置增強(qiáng)。那么我們?nèi)绾卧O(shè)置其增強(qiáng)的順序呢?

我們通過在增強(qiáng)類上面添加注解 @Order(數(shù)字類型值),數(shù)字類型值越小優(yōu)先級(jí)越高 ,來保證增強(qiáng)的順尋,代碼如下:

@Component
@Aspect
@Order(2)
public class PersonProxy {
    //前置通知
    @Before(value = "execution(* com.wyf.aopanno.User.add(..))")
    public void before(){
        System.out.println("Person Before****");
    }
}

三、結(jié)束

本文主要介紹了AOP關(guān)鍵子以及基于注解的AOP操作,通過一個(gè)實(shí)例,介紹了AOP的前置通知、后置通知、異常通知、最終通知以及環(huán)繞通知。

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!   

相關(guān)文章

  • JVM內(nèi)存增強(qiáng)之逃逸分析

    JVM內(nèi)存增強(qiáng)之逃逸分析

    逃逸分析一種數(shù)據(jù)分析算法,基于此算法可以有效減少Java對(duì)象在堆內(nèi)存中的分配。本文將詳細(xì)講講逃逸分析的原理與實(shí)現(xiàn),需要的可以參考一下
    2022-09-09
  • centos 安裝java環(huán)境的多種方法

    centos 安裝java環(huán)境的多種方法

    本文給大家分享三種方法幫助大家安裝jdk,有利用yum來安裝jdk還有通過手動(dòng)解壓jdk的操作方法,每種方法給大家介紹的都非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2021-05-05
  • Java中集合和數(shù)組的排序方式小結(jié)

    Java中集合和數(shù)組的排序方式小結(jié)

    這篇文章主要介紹了Java中集合和數(shù)組的排序方式小結(jié),本文講解了對(duì)數(shù)字?jǐn)?shù)組、字符數(shù)組排序以及集合序列的排序,需要的朋友可以參考下
    2015-01-01
  • 一篇文章輕松搞懂Java中的自旋鎖

    一篇文章輕松搞懂Java中的自旋鎖

    隨著互聯(lián)網(wǎng)的蓬勃發(fā)展,越來越多的互聯(lián)網(wǎng)企業(yè)面臨著用戶量膨脹而帶來的并發(fā)安全問題。這篇文章主要給大家介紹了關(guān)于Java中自旋鎖的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Java具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Java集合排序規(guī)則接口Comparator用法解析

    Java集合排序規(guī)則接口Comparator用法解析

    這篇文章主要介紹了Java集合排序規(guī)則接口Comparator用法解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • java基于poi導(dǎo)出excel透視表代碼實(shí)例

    java基于poi導(dǎo)出excel透視表代碼實(shí)例

    這篇文章主要介紹了java基于poi導(dǎo)出excel透視表代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • Java數(shù)組動(dòng)態(tài)增加容量過程解析

    Java數(shù)組動(dòng)態(tài)增加容量過程解析

    這篇文章主要介紹了Java數(shù)組動(dòng)態(tài)增加容量過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • 如何根據(jù)帶賬號(hào)密碼的WSDL地址生成JAVA代碼

    如何根據(jù)帶賬號(hào)密碼的WSDL地址生成JAVA代碼

    這篇文章主要介紹了如何根據(jù)帶賬號(hào)密碼的WSDL地址生成JAVA代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • Java實(shí)現(xiàn)字符串的分割(基于String.split()方法)

    Java實(shí)現(xiàn)字符串的分割(基于String.split()方法)

    Java中的我們可以利用split把字符串按照指定的分割符進(jìn)行分割,然后返回字符串?dāng)?shù)組,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)字符串的分割的相關(guān)資料,是基于jDK1.8版本中的String.split()方法,需要的朋友可以參考下
    2022-09-09
  • WebSocket 中使用 @Autowired 注入對(duì)應(yīng)為null的解決方案

    WebSocket 中使用 @Autowired 注入對(duì)應(yīng)為null的解決方案

    SpringBoot集成WebSocket時(shí),會(huì)遇到service對(duì)象為null的情況,原因是Spring默認(rèn)為單例模式與WebSocket的多對(duì)象模式相沖突,當(dāng)客戶端與服務(wù)器端建立連接時(shí),會(huì)創(chuàng)建新的WebSocket對(duì)象,本文給大家介紹WebSocket 中使用 @Autowired 注入對(duì)應(yīng)為null的問題,感興趣的朋友一起看看吧
    2024-10-10

最新評(píng)論

沧州市| 社旗县| 林芝县| 清涧县| 神池县| 青田县| 苍山县| 中卫市| 龙陵县| 忻城县| 法库县| 拉孜县| 偃师市| 方山县| 定安县| 伊宁市| 义乌市| 从江县| 曲阳县| 东山县| 宾阳县| 望都县| 腾冲县| 息烽县| 黄骅市| 八宿县| 平安县| 松桃| 安新县| 中宁县| 新邵县| 新密市| 钟山县| 涞水县| 塔城市| 丹阳市| 平陆县| 和田市| 襄汾县| 新安县| 弥渡县|