国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring之AOP(帶你一篇文章搞定AOP)

這篇具有很好參考價值的文章主要介紹了Spring之AOP(帶你一篇文章搞定AOP)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。


前言

Spring的核心之一:AOP


一、AOP概述和原理

用的依賴(包括上篇文章講訴的IOC依賴):

       <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.2</version>
            </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>6.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.19</version>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>aopalliance</groupId>
            <artifactId>aopalliance</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.cglib</groupId>
            <artifactId>com.springsource.net.sf.cglib</artifactId>
            <version>2.1.3</version>
        </dependency>

1.概述和原理

  • AOP:面向切面編程。利用 AOP 可以對業(yè)務(wù)邏輯的各個部分進行隔離,從而使得業(yè)務(wù)邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發(fā)的效率。通俗來說就是在不修改代碼的情況下添加新的功能。
  • 底層通過動態(tài)代理實現(xiàn):
    (1)有接口情況:使用JDK動態(tài)代理,即創(chuàng)建接口實現(xiàn)類的代理對象。
    (2)無接口情況:使用CGLIB動態(tài)代理,即創(chuàng)建當(dāng)前類子類的代理對象。

2.JDK動態(tài)代理實例

核心:

  • 通過 java.lang.reflect.Proxy類 的 newProxyInstance方法 創(chuàng)建代理類。
  • newProxyInstance方法
    Spring之AOP(帶你一篇文章搞定AOP),spring,java,后端,AOP
    參數(shù)一:類加載器
    參數(shù)二:所增強方法所在的類,這個類實現(xiàn)的接口,支持多個接口
    參數(shù)三:實現(xiàn)InvocationHandle接口,重寫invoke方法來添加新的功能
    模擬代理:
    UserDao、UserDaoImpl類:
package com.dragon.springaop;

public interface UserDao {
    public int add(int a,int b);
    public String update(String id);
}
================================================
package com.dragon.springaop;

public class UserDaoImpl implements UserDao{
    @Override
    public int add(int a,int b) {
        System.out.println("add方法執(zhí)行了...");
        return a+b;
    }

    @Override
    public String update(String id) {
        System.out.println("update方法執(zhí)行了...");
        return id;
    }
}

JDKProxy類(通過 java.lang.reflect.Proxy類 的 newProxyInstance方法創(chuàng)建代理類):

package com.dragon.springaop;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class JDKProxy {
    public static void main(String[] args) {
        Class[] interfaces={UserDao.class};//創(chuàng)建接口實現(xiàn)類代理對象
        UserDaoImpl userDao=new UserDaoImpl();
        UserDao dao=(UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(),interfaces,new UserDaoProxy(userDao)) ;
        int result=dao.add(1,2);
        System.out.println("result:"+result);
    }
}
class UserDaoProxy implements InvocationHandler{

    //創(chuàng)建的是誰的代理對象,把誰傳遞過來
    //有參構(gòu)造傳遞
    private Object obj;
    public UserDaoProxy (Object obj){
        this.obj=obj;
    }
	//參數(shù)含義:代理對象、方法、參數(shù)
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("方法之前執(zhí)行...."+ method.getName()+":傳遞參數(shù)...."+ Arrays.toString(args));
        Object res=method.invoke(obj,args);
        System.out.println("方法之后執(zhí)行...."+obj);
        return res;
    }
}

Spring之AOP(帶你一篇文章搞定AOP),spring,java,后端,AOP
其實JDK動態(tài)代理本質(zhì)就是在原來要增強的方法前面或后面增加一些邏輯處理等,而不修改源代碼。從上面運行結(jié)果看以看出,add方法執(zhí)行結(jié)果是3,但是在執(zhí)行add方法執(zhí)行多一些語句輸出,這些就是我們增加的邏輯處理部分。其中method.invoke()就是模擬的原add方法執(zhí)行,而前后的輸出語句是模擬的增強的代碼

二、基于AspectJ實現(xiàn)的AOP操作

1.什么是AspectJ

AspectJ不是Spring組成部分,獨立AOP框架,一般把AspectJ和Spring框架一起使用進行AOP操作。

2.AOP相關(guān)術(shù)語

  • 連接點:類中可以被增強的方法,稱為連接點。
  • 切入點:實際被增強的方法,稱為切入點。
  • 通知:增強的那一部分邏輯代碼。通知有多種類型:
    (1)前置通知:增強部分代碼在原代碼前面。
    (2)后置通知:增強部分代碼在原代碼后面。
    (3)環(huán)繞通知:增強部分代碼既有在原代碼前面,也有在原代碼后面。
    (4)異常通知:原代碼發(fā)生異常后才會執(zhí)行。
    (5)最終通知:類似與finally那一部分
  • 切面:指把通知應(yīng)用到切入點這一個動作。

3.切點表達(dá)式

  • 語法:execution([權(quán)限修飾符] [返回類型] [類全路徑] [方法名稱] [參數(shù)列表])
  • 例1:對 com.atguigu.dao.BookDao 類里面的 add 進行增強
execution(* com.auguigu.dao.BookDao.add(..))
  • 例2:對 com.atguigu.dao.BookDao 類里面的所有的方法進行增強
execution(* com.atguigu.dao.BookDao.*(..))
  • 例3:對 com.atguigu.dao 包里面所有類,類里面所有方法進行增強
execution(* com.atguigu.dao.*.* (..))

3.基于注解方式實現(xiàn)

(1)實例:

User:
注解方式創(chuàng)建User對象user

package com.dragon.springaop.anno;

import org.springframework.stereotype.Component;

@Component
public class User {
    public void add(){
        System.out.println("add....");
    }
}

UserProxy類(先忽略@Order注解):
注解方式創(chuàng)建UserProxy對象userProxy
@Aspect定義UserProxy為切面類(即指把通知應(yīng)用到切入點的類)

package com.dragon.springaop.anno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect//定義切面類
@Order(3)
public class UserProxy {
    @Before(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void before(){
        System.out.println("before.....");
    }
    @AfterReturning(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void afterReturning(){
        System.out.println("afterReturning....");
    }
    @After(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void after(){
        System.out.println("after....");
    }
    @AfterThrowing(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void afterThrowing(){
        System.out.println("afterThrowing....");
    }
    @Around(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable{
        System.out.println("環(huán)繞之前....");
            proceedingJoinPoint.proceed();
        System.out.println("環(huán)繞之后....");
    }
}

spring配置文件:

<?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.dragon.springaop.anno"/>
        <!--開啟AspectJ生成代理對象-->
        <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

測試:

 	ApplicationContext context=new ClassPathXmlApplicationContext("beanaop1.xml");
        User user=context.getBean("user", User.class);
        user.add();

Spring之AOP(帶你一篇文章搞定AOP),spring,java,后端,AOP
可以看出Befoe(前置通知,在add前運行)、AfterRetruning(后置通知或返回通知,在add返回值后運行)、AfterThrowing(異常通知,在add出現(xiàn)異常后,這個沒有運行,因為沒異常,大家在add內(nèi)添加 int i=1/0 測試一下,不在演示)、After(最終通知,在add執(zhí)行完后)、Around(環(huán)繞通知,在add前和后)的運行時期。

(2)切入點提取

上面的UserProxy 類中有很多重復(fù)的切入點表達(dá)式,可以進行公共提取

@Pointcut(value = "execution(* com.dragon.springaop.anno.User.add(..))")
public void pointDemo(){    
}

//前置通知
@Before(value="pointDemo()")
public void before(){
    System.out.println("before....");
}

(3)設(shè)置增強類優(yōu)先級

上面的實例只有UserProxy一個增強類,當(dāng)有多個增強類時,可以使用@Order(數(shù)值)設(shè)置優(yōu)先級執(zhí)行。(數(shù)字越小優(yōu)先級越高)
在上訴例子中多創(chuàng)建一個PeopleProxy類,設(shè)置@Order:

package com.dragon.springaop.anno;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.junit.jupiter.api.Order;
import org.springframework.stereotype.Component;

@Component
@Aspect
@Order(1)
public class PersionProxy {
    @Before(value = "execution(* com.dragon.springaop.anno.User.add(..))")
    public void persionBefore(){
        System.out.println("persionBefore.....");
    }
}

上面的UserProxy類中我設(shè)置的是Order(3),所以PeopleProxylei類先運行。
Spring之AOP(帶你一篇文章搞定AOP),spring,java,后端,AOP

(4)完全注解開發(fā)

AOPConfig類:

package com.dragon.springaop.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan(basePackages = {"com.dragon.springaop"})
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
}

Book、BookProxy:

package com.dragon.springaop.aopxml;

import org.springframework.stereotype.Component;

@Component
public class Book {
    public void buy(){
        System.out.println("buy......");
    }
}

========================================
package com.dragon.springaop.aopxml;

public class BookProxy {
    public void before(){
        System.out.println("before....");
    }
}

測試:

		ApplicationContext context=new AnnotationConfigApplicationContext(AopConfig.class);
        Book book=context.getBean("book", Book.class);
        book.buy();

4.基于xml配置文件實現(xiàn)(了解)

Book、BookProxy:

package com.dragon.springaop.aopxml;

import org.springframework.stereotype.Component;

public class Book {
    public void buy(){
        System.out.println("buy......");
    }
}

========================================
package com.dragon.springaop.aopxml;

public class BookProxy {
    public void before(){
        System.out.println("before....");
    }
}

spring配置文件:

 <bean id="book" class="com.dragon.springaop.aopxml.Book"></bean>
    <bean id="bookProxy" class="com.dragon.springaop.aopxml.BookProxy"></bean>

<!--    配置aop增強-->
    <aop:config>
<!--        切入點-->
        <aop:pointcut id="p" expression="execution(* com.dragon.springaop.aopxml.Book.buy(..))"/>
<!--        配置切面-->
        <aop:aspect ref="bookProxy">
<!--            增強作用在具體的方法上-->
            <aop:before method="before" pointcut-ref="p"></aop:before>
        </aop:aspect>
    </aop:config>

測試:

		ApplicationContext context=new ClassPathXmlApplicationContext("beanaop2.xml");
        Book book=context.getBean("book", Book.class);
        book.buy();

總結(jié)

以上就是AOP的講解。文章來源地址http://www.zghlxwxcb.cn/news/detail-604100.html

到了這里,關(guān)于Spring之AOP(帶你一篇文章搞定AOP)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 一篇文章搞定《APP的啟動流程》

    一篇文章搞定《APP的啟動流程》

    前面已經(jīng)鋪墊了Binder、Handler、View的繪制流程 那么該來看看APP的啟動流程了,是如何啟動了我們這些重要的組件 本文會按照步驟和啟動需要的成員并附帶一點點源碼進行講解。 以了解熟悉啟動的流程為主。不會大篇幅的利用源碼深入。 本文結(jié)構(gòu): 1、冷啟動、溫啟動、熱啟

    2024年02月16日
    瀏覽(21)
  • 一篇文章搞定克拉美羅界(CRB)

    一篇文章搞定克拉美羅界(CRB)

    二郎最近在研究LBL(長基線)定位,大部分論文都提到了文中算法獲得的方差接近CRB,所以自己的算法性能較好。于是二郎就想知道克拉美羅界是什么意思,以及能應(yīng)用的場景。 1)查文檔: 克拉美羅界:為無偏估計量的方差確定一個下界,衡量無偏估計的性能。 無偏估計:

    2024年02月15日
    瀏覽(22)
  • 一篇文章搞定Android權(quán)限問題(全版本)

    一篇文章搞定Android權(quán)限問題(全版本)

    文章內(nèi)容如下: 如果你只是想快速的完成你Android權(quán)限申請的工作,那么直接上工具PermissionX 如果是想真正的了解Android的權(quán)限問題,那么建議你用15分鐘通讀一下本文。(可以不去實驗,收藏以備后用) 首先了解Android版本和SDK的關(guān)系,幫助我們分辨后面的權(quán)限版本。 其次把最常

    2023年04月20日
    瀏覽(20)
  • 一篇文章搞定《Android權(quán)限問題(全版本)》

    一篇文章搞定《Android權(quán)限問題(全版本)》

    文章內(nèi)容如下: 如果你只是想快速的完成你Android權(quán)限申請的工作,那么直接上工具PermissionX 如果是想真正的了解Android的權(quán)限問題,那么建議你用15分鐘通讀一下本文。(可以不去實驗,收藏以備后用) 首先了解Android版本和SDK的關(guān)系,幫助我們分辨后面的權(quán)限版本。 其次把最常

    2024年02月03日
    瀏覽(67)
  • 【Unity】一篇文章搞定AStar(A*)算法

    【Unity】一篇文章搞定AStar(A*)算法

    AStar(A*)算法,是一種在靜態(tài)網(wǎng)格中求解最短路徑直接有效的搜索方法。在游戲開發(fā)中,A*算法常應(yīng)用于部分RPG游戲和策略戰(zhàn)棋類游戲。對于Unity開發(fā)者來說,掌握A*算法也是十分有必要的。不過在了解A*算法之前,有必要先回顧一下深度優(yōu)先算法(DFS)、廣度優(yōu)先算法(BFS)

    2024年02月02日
    瀏覽(20)
  • Spring Boot 3 + JWT + Security 聯(lián)手打造安全帝國:一篇文章讓你掌握未來!

    Spring Boot 3 + JWT + Security 聯(lián)手打造安全帝國:一篇文章讓你掌握未來!

    Spring Security 已經(jīng)成為 java 后臺權(quán)限校驗的第一選擇.今天就通過讀代碼的方式帶大家深入了解一下Security,本文主要是基于開源項目spring-boot-3-jwt-security來講解Spring Security + JWT(Json Web Token).實現(xiàn)用戶鑒權(quán),以及權(quán)限校驗. 所有代碼基于 jdk17+ 構(gòu)建.現(xiàn)在讓我們開始吧! Springboot 3.0 Spri

    2024年02月07日
    瀏覽(89)
  • 一篇文章搞定Java中常用集合的排序方法

    一篇文章搞定Java中常用集合的排序方法

    目錄 Array · 數(shù)組 List · 列表 Collections.sort() 簡單類型 復(fù)雜對象 類 使用Lambda表達(dá)式 Stream API Map · 鍵值對 對 Map 的 Key 進行排序 對 Map 的 Value 進行排序 最近在做算法題的時候,發(fā)現(xiàn)排序在大部分題中都不可或缺,今天心血來潮,總結(jié)下Java中集合排序常用的方法,基本覆蓋了大

    2024年02月09日
    瀏覽(26)
  • 一篇文章搞定什么是nodeJs它和NPM關(guān)系與應(yīng)用

    現(xiàn)在前端的入門門檻越來越高了,不再是單純 html+css+js ,各種前端框架 層出不窮,各種ui組件庫層出不窮。 模塊化,打包化,各種工具庫層出不窮,前端變成 大前端 ,甚至前端可以搞定整個項目,通過 node 作為服務(wù)端api, 這里我們主角就是 nodeJs javaScript是一門腳本語言,

    2024年02月03日
    瀏覽(27)
  • 一篇文章搞定《動手學(xué)深度學(xué)習(xí)》-(李沐)PyTorch版本的所有內(nèi)容

    一篇文章搞定《動手學(xué)深度學(xué)習(xí)》-(李沐)PyTorch版本的所有內(nèi)容

    目錄 目錄 簡介 閱讀指南 1. 深度學(xué)習(xí)簡介 2. 預(yù)備知識 3. 深度學(xué)習(xí)基礎(chǔ) 4. 深度學(xué)習(xí)計算 5. 卷積神經(jīng)網(wǎng)絡(luò) 6. 循環(huán)神經(jīng)網(wǎng)絡(luò) 7. 優(yōu)化算法 8. 計算性能 9. 計算機視覺 10. 自然語言處理 環(huán)境 參考(大家可以在這里下載代碼) 原書地址(大家可以在這里閱讀電子版PDF內(nèi)容) 引用 閱讀

    2023年04月24日
    瀏覽(49)
  • 一篇文章搞定《實戰(zhàn)中的設(shè)計模式之Android版》

    一篇文章搞定《實戰(zhàn)中的設(shè)計模式之Android版》

    其實大多數(shù)可能和我一樣,在開發(fā)項目的累積經(jīng)驗下,和對設(shè)計模式隱約的記憶下。 在開發(fā)項目的過程中其實已經(jīng)使用到了設(shè)計模式,但是不能自知。 比如:之前開發(fā)的基于AI的一個對話IM,里面涉及到了很多的設(shè)計模式。但是都是下意識的去使用,甚至連他是那種設(shè)計模式

    2024年02月10日
    瀏覽(24)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包