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

一文吃透 Spring 中的 AOP 編程

 更新時間:2023年04月04日 10:53:08   作者:Java Fans  
這篇文章主要介紹了springboot中的AOP編程,本文介紹的非常詳細(xì),有一定的參考價值,感興趣的小伙伴可以借鑒一下

AOP 概述

AOP 為 Aspect Oriented Programming 的縮寫,是面向切面編程,通過預(yù)編譯方式和運行期動態(tài)代理實現(xiàn)程序功能的統(tǒng)一維護的一種技術(shù)。AOP 是 OOP 的延續(xù),是軟件開發(fā)中的一個熱點,也是 Spring 框架中的一個重要內(nèi)容,是函數(shù)式編程的一種衍生范型

AOP 可以分離業(yè)務(wù)代碼和關(guān)注點代碼(重復(fù)代碼),在執(zhí)行業(yè)務(wù)代碼時,動態(tài)的注入關(guān)注點代碼。切面就是關(guān)注點代碼形成的類。Spring AOP 中的動態(tài)代理主要有兩種方式,JDK 動態(tài)代理和 CGLIB 動態(tài)代理。JDK 動態(tài)代理通過反射來接收被代理的類,并且要求被代理的類必須實現(xiàn)一個接口

AOP 實現(xiàn)分類

AOP 要達到的效果是,保證開發(fā)者不修改源代碼的前提下,去為系統(tǒng)中的業(yè)務(wù)組件添加某種通用功能,按照 AOP 框架修改源代碼的時機,可以將其分為兩類:

  • 靜態(tài) AOP 實現(xiàn), AOP 框架在編譯階段對程序源代碼進行修改,生成了靜態(tài)的 AOP 代理類(生成的 *.class 文件已經(jīng)被改掉了,需要使用特定的編譯器),比如 AspectJ。
  • 動態(tài) AOP 實現(xiàn), AOP 框架在運行階段對動態(tài)生成代理對象(在內(nèi)存中以 JDK 動態(tài)代理,或 CGlib 動態(tài)地生成 AOP 代理類),如 SpringAOP

AOP 術(shù)語

  • 連接點(JointPoint):與切入點匹配的執(zhí)行點,在程序整個執(zhí)行流程中,可以織入切面的位置,方法的執(zhí)行前后,異常拋出的位置
  • 切點(PointCut):在程序執(zhí)行流程中,真正織入切面的方法。
  • 切面(ASPECT):切點+通知就是切面
  • 通知(Advice):切面必須要完成的工作,也叫增強。即,它是類中的一個方法,方法中編寫織入的代碼。
  • 前置通知 后置通知
    • 環(huán)繞通知 異常通知
    • 最終通知
  • 目標(biāo)對象(Target):被織入通知的對象
  • 代理對象(Proxy):目標(biāo)對象被織入通知之后創(chuàng)建的新對象

通知的類型

Spring 方面可以使用下面提到的五種通知工作:

通知描述
前置通知在一個方法執(zhí)行之前,執(zhí)行通知。
最終通知在一個方法執(zhí)行之后,不考慮其結(jié)果,執(zhí)行通知。
后置通知在一個方法執(zhí)行之后,只有在方法成功完成時,才能執(zhí)行通知。
異常通知在一個方法執(zhí)行之后,只有在方法退出拋出異常時,才能執(zhí)行通知。
環(huán)繞通知在一個方法調(diào)用之前和之后,執(zhí)行通知。

基于 Aspectj 實現(xiàn) AOP 操作

基于 Aspectj 實現(xiàn) AOP 操作,經(jīng)歷了下面三個版本的變化,注解版是我們最常用的。

切入點表達式

作用:聲明對哪個類中的哪個方法進行增強

語法:

execution([訪問權(quán)限修飾符] 返回值 [ 類的全路徑名 ] 方法名 (參數(shù)列表)[異常])

  • 訪問權(quán)限修飾符:
    • 可選項,不寫就是四個權(quán)限都包含
    • 寫public就表示只包括公開的方法
  • 返回值類型
    • 必填項 * 標(biāo)識返回值任意
  • 全限定類名
    • 可選項,兩個點 … 表示當(dāng)前包以及子包下的所有類,省略表示所有類
  • 方法名
    • 必填項 * 表示所有的方法 set*表示所有的set方法
  • 形參列表
    • 必填項
    • ()表示沒有參數(shù)的方法
    • (…)參數(shù)類型和參數(shù)個數(shù)隨意的方法
    • (*)只有一個參數(shù)的方法
    • (*,String) 第一個參數(shù)類型隨意,第二個參數(shù)String類型
  • 異常信息
    • 可選項 省略時標(biāo)識任何異常信息

第一版:基于xml(aop:config)配置文件

使用 Spring AOP 接口方式實現(xiàn) AOP, 可以通過自定義通知來供 Spring AOP 識別對應(yīng)實現(xiàn)的接口是:

  1. 前置通知:MethodBeforeAdvice
  2. 返回通知:AfterReturningAdvice
  3. 異常通知:ThrowsAdvice
  4. 環(huán)繞通知:MethodInterceptor

實現(xiàn)步驟:

1、定義業(yè)務(wù)接口

/**
 * 使用接口方式實現(xiàn)AOP, 默認(rèn)通過JDK的動態(tài)代理來實現(xiàn). 非接口方式, 使用的是cglib實現(xiàn)動態(tài)代理
 */

package cn.kgc.spring05.entity;

public interface Teacher {
    String teachOnLine(String course);
    String teachOffLine(Integer course);
}

2、定義實現(xiàn)類

package cn.kgc.spring05.entity;

public class TeacherA implements Teacher{
    @Override
    public String teachOnLine(String course) {
        System.out.println("TeacherA開始"+course+"課程線上教學(xué)");
        if(course.equals("java")){
            throw new RuntimeException("入門到放棄!");
        }
        return course+"課程線上教學(xué)";
    }

    @Override
    public String teachOffLine(Integer course) {
        System.out.println("TeacherA開始"+course+"課程線下教學(xué)");
        return course+"課程線下教學(xué)";
    }
}

3、實現(xiàn)接口定義通知類

前置通知類

package cn.kgc.spring05.advice;

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

//前置通知
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("------------spring aop 前置通知------------");
    }
}

后置通知類

package cn.kgc.spring05.advice;

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class MyAfterReturnAdvice implements AfterReturningAdvice {
    @Override
    public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
        System.out.println("------------spring aop 后置通知------------");
    }
}

4、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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--托管通知-->
    <bean id="after" class="cn.kgc.spring05.advice.MyAfterReturnAdvice"></bean>
    <bean id="before" class="cn.kgc.spring05.advice.MyMethodBeforeAdvice"></bean>
    <bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean>
    <!--AOP的配置-->
    <aop:config>
        <!--切點表達式-->
        <aop:pointcut id="pt" expression="execution(* *(..))"/>
        <aop:advisor advice-ref="before" pointcut-ref="pt"></aop:advisor>
        <aop:advisor advice-ref="after" pointcut-ref="pt"></aop:advisor>
    </aop:config>
</beans>

5、測試

package cn.kgc.spring05;

import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

/**
 * Unit test for simple App.
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class AppTest
{
    @Autowired
    Teacher teacher;

    @Test
    public void teachOnLine() {
        System.out.println(teacher.getClass());
        String s = teacher.teachOnLine("java");
        System.out.println("s = " + s);
    }
}

6、運行結(jié)果

第二版:基于xml(aop:aspect)配置文件

基于 xml(aop:config) 配置文件的方式,增加幾個通知,就會創(chuàng)建幾個通知類,那我們能否將這些通知類寫在一個類中呢?下面就讓我來帶你們找到解決之法!

配置 AspectJ 標(biāo)簽解讀表

實現(xiàn)步驟:

1、定義業(yè)務(wù)接口

/**
 * 使用接口方式實現(xiàn)AOP, 默認(rèn)通過JDK的動態(tài)代理來實現(xiàn). 非接口方式, 使用的是cglib實現(xiàn)動態(tài)代理
 */

package cn.kgc.spring05.entity;

public interface Teacher {
    String teachOnLine(String course);
    String teachOffLine(Integer course);
}

2、定義實現(xiàn)類

package cn.kgc.spring05.entity;

public class TeacherA implements Teacher{
    @Override
    public String teachOnLine(String course) {
        System.out.println("TeacherA開始"+course+"課程線上教學(xué)");
        if(course.equals("java")){
            throw new RuntimeException("入門到放棄!");
        }
        return course+"課程線上教學(xué)";
    }

    @Override
    public String teachOffLine(Integer course) {
        System.out.println("TeacherA開始"+course+"課程線下教學(xué)");
        return course+"課程線下教學(xué)";
    }
}

3、實現(xiàn)接口定義通知類

package cn.kgc.spring05.advice;

public class AllAdvice {
    public void before(){System.out.println("------------前置通知--------------");}

    public void afterReturning(){System.out.println("------------后置通知--------------");}

    public void afterThrowing(){System.out.println("------------異常通知--------------");}

    public void after(){System.out.println("------------最終通知--------------");}

    public void around(){System.out.println("------------環(huán)繞通知--------------");}
}

4、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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--托管通知-->
    <bean id="all" class="cn.kgc.spring05.advice.AllAdvice"></bean>
    <bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean>
    <!--AOP的配置-->
    <aop:config>
        <!--切點表達式-->
        <aop:pointcut id="pt" expression="execution(* *(String))"/>
        <aop:aspect ref="all">
            <aop:before method="before" pointcut-ref="pt"></aop:before>
            <aop:after-returning method="afterReturning" pointcut-ref="pt"></aop:after-returning>
            <aop:after-throwing method="afterThrowing" pointcut-ref="pt"></aop:after-throwing>
            <aop:after method="after" pointcut-ref="pt"></aop:after>
<!--            <aop:around method="around" pointcut-ref="pt"></aop:around>-->
        </aop:aspect>
    </aop:config>
</beans>

5、測試

package cn.kgc.spring05.advice;

import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config2.xml")
public class AllAdviceTest{

    @Autowired
    Teacher teacher;

    @Test
    public void test01() {
        System.out.println(teacher.getClass());
        String s = teacher.teachOnLine("java");
        System.out.println("s = " + s);
    }
}

6、運行結(jié)果

第三版:基于注解實現(xiàn)通知

  • 常用 “通知” 注解如下:

@Aspect 注解將此類定義為切面。
@Before 注解用于將目標(biāo)方法配置為前置增強(前置通知)。
@AfterReturning 注解用于將目標(biāo)方法配置為后置增強(后置通知)。
@Around 定義環(huán)繞增強(環(huán)繞通知)
@AfterThrowing 配置異常通知
@After 也是后置通知,與 @AfterReturning 很相似,區(qū)別在于 @AfterReturning 在方法執(zhí)行完畢后進行返回,可以有返回值。@After 沒有返回值。

實現(xiàn)步驟:

1、定義業(yè)務(wù)接口

/**
 * 使用接口方式實現(xiàn)AOP, 默認(rèn)通過JDK的動態(tài)代理來實現(xiàn). 非接口方式, 使用的是cglib實現(xiàn)動態(tài)代理
 */

package cn.kgc.spring05.entity;

public interface Teacher {
    String teachOnLine(String course);
    String teachOffLine(Integer course);
}

2、定義注解

package cn.kgc.spring05.advice;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoAdvice {
}

3、定義實現(xiàn)類

package cn.kgc.spring05.entity;

import cn.kgc.spring05.advice.AnnoAdvice;
import org.springframework.stereotype.Component;

@Component
public class TeacherA implements Teacher{
    @Override
    @AnnoAdvice
    public String teachOnLine(String course) {
        System.out.println("TeacherA開始"+course+"課程線上教學(xué)");
        if(course.equals("java")){
            throw new RuntimeException("入門到放棄!");
        }
        return course+"課程線上教學(xué)";
    }

    @Override
    @AnnoAdvice
    public String teachOffLine(Integer course) {
        System.out.println("TeacherA開始"+course+"課程線下教學(xué)");
        return course+"課程線下教學(xué)";
    }
}

4、實現(xiàn)接口定義切面類

首先在類上面添加 @Aspect 注解,將該類轉(zhuǎn)化為切面類,再在類中的各個方法上面使用各自的 “通知” 注解即可實現(xiàn)。

package cn.kgc.spring05.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class AllAdvice {

    @Pointcut("@annotation(AnnoAdvice)")
    public void point(){}

    @Before("point()")
    public void before(){System.out.println("------------前置通知--------------");}

    @AfterReturning("point()")
    public void afterReturning(){System.out.println("------------后置通知--------------");}

    @AfterThrowing("point()")
    public void afterThrowing(){System.out.println("------------異常通知--------------");}

    @After("point()")
    public void after(){System.out.println("------------最終通知--------------");}

    @Around("point()")
    public Object aroundAdvice(ProceedingJoinPoint joinPoint){

        Object proceed = null;
        try {
            System.out.println("----------spring aop 環(huán)繞 前通知-----------");
            proceed = joinPoint.proceed();
            System.out.println("----------spring aop 環(huán)繞 后通知-----------");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
            System.out.println("----------spring aop 環(huán)繞 異常通知-----------");
        }finally {
            System.out.println("----------spring aop 環(huán)繞 最終通知-----------");
        }
        return proceed;
    }
}

5、XML 配置方式

開啟包掃描和aspectj自動代理

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    <!--開啟包掃描-->
    <context:component-scan base-package="cn.kgc.spring05"></context:component-scan>
    <!--開啟aspectj自動代理-->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

6、測試

package cn.kgc.spring05.advice;

import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config3.xml")
public class AllAdviceTest{

    @Autowired
    Teacher teacher;

    @Test
    public void test01() {
        System.out.println(teacher.getClass());
        String s = teacher.teachOnLine("html");
        System.out.println("s = " + s);
    }
}

7、運行效果

 到此這篇關(guān)于一文吃透 Spring 中的 AOP 編程的文章就介紹到這了,更多相關(guān)Java Spring AOP編程內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實現(xiàn)的簡單網(wǎng)頁截屏功能示例

    Java實現(xiàn)的簡單網(wǎng)頁截屏功能示例

    這篇文章主要介紹了Java實現(xiàn)的簡單網(wǎng)頁截屏功能,涉及java網(wǎng)頁打開及屏幕截圖功能相關(guān)操作技巧,需要的朋友可以參考下
    2017-12-12
  • Java 加密解密基礎(chǔ)分類及模式歸納整理

    Java 加密解密基礎(chǔ)分類及模式歸納整理

    這篇文章主要介紹了Java加密解密基礎(chǔ)分類方法匯總的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • SpringBoot 增量部署發(fā)布的實現(xiàn)步驟

    SpringBoot 增量部署發(fā)布的實現(xiàn)步驟

    本文介紹了通過拆分項目jar包和使用類加載器實現(xiàn)Spring Boot的增量部署,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • java中l(wèi)ist的用法和實例講解

    java中l(wèi)ist的用法和實例講解

    這篇文章主要介紹了java中l(wèi)ist的用法和實例講解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • SpringBoot?配置多個JdbcTemplate的實現(xiàn)步驟

    SpringBoot?配置多個JdbcTemplate的實現(xiàn)步驟

    本文介紹了在SpringBoot中配置多個JdbcTemplate的方法,包括創(chuàng)建項目、添加依賴、配置數(shù)據(jù)源和多個JdbcTemplate的使用,感興趣的可以了解一下
    2024-11-11
  • SpringBoot3 Spring WebFlux簡介(推薦)

    SpringBoot3 Spring WebFlux簡介(推薦)

    SpringWebFlux是Spring Framework 5中引入的響應(yīng)式Web框架,用于支持非阻塞異步通信和響應(yīng)式流處理,與傳統(tǒng)的SpringMVC相比,WebFlux提供了完全異步非阻塞的編程模型,適用高并發(fā)、微服務(wù)架構(gòu)和實時數(shù)據(jù)流,本文介紹SpringBoot3 Spring WebFlux簡介,感興趣的朋友一起看看吧
    2024-10-10
  • 詳解Java Spring各種依賴注入注解的區(qū)別

    詳解Java Spring各種依賴注入注解的區(qū)別

    這篇文章主要介紹了詳解Java Spring各種依賴注入注解的區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Java 面試題和答案 -(上)

    Java 面試題和答案 -(上)

    本文主要介紹Java 面試題和答案,這里整理了Java面試中出現(xiàn)的各種題型,和相應(yīng)知識點,有需要的小伙伴可以好好參考下,幫助大家面試成功
    2016-09-09
  • JVM內(nèi)存模型知識點總結(jié)

    JVM內(nèi)存模型知識點總結(jié)

    在本篇文章里小編給大家分享了關(guān)于JVM內(nèi)存模型的學(xué)習(xí)心得以及相關(guān)知識點總結(jié),有興趣的朋友們跟著學(xué)習(xí)下。
    2019-05-05
  • JAVA 多線程之信號量(Semaphore)實例詳解

    JAVA 多線程之信號量(Semaphore)實例詳解

    這篇文章主要介紹了JAVA 多線程之信號量(Semaphore)實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-01-01

最新評論

宜都市| 科技| 开江县| 澜沧| 廉江市| 博客| 武强县| 赣州市| 河北省| 麻城市| 神木县| 江阴市| 衢州市| 安达市| 浦北县| 绥宁县| 正阳县| 蓬安县| 宁南县| 大竹县| 泸溪县| 临江市| 桃园县| 汽车| 万盛区| 正安县| 南召县| 泗阳县| 宽甸| 肃南| 庆阳市| 阜新市| 永仁县| 武陟县| 石嘴山市| 广宗县| 商水县| 宽甸| 榆社县| 罗源县| 镇巴县|