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

基于spring AOP @Around @Before @After的區(qū)別說明

 更新時(shí)間:2021年02月19日 12:02:16   作者:Rainyn  
這篇文章主要介紹了基于spring AOP @Around @Before @After的區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧

此段小代碼演示了spring aop中@Around @Before @After三個(gè)注解的區(qū)別

@Before是在所攔截方法執(zhí)行之前執(zhí)行一段邏輯。

@After 是在所攔截方法執(zhí)行之后執(zhí)行一段邏輯。

@Around是可以同時(shí)在所攔截方法的前后執(zhí)行一段邏輯。

連接點(diǎn)(JoinPoint) 這個(gè)就更好解釋了,就是spring允許你是通知(Advice)的地方,那可就真多了,基本每個(gè)方法的前、后(兩者都有也行),或拋出異常是時(shí)都可以是連接點(diǎn),spring只支持方法連接點(diǎn)。

其他如AspectJ還可以讓你在構(gòu)造器或?qū)傩宰⑷霑r(shí)都行,不過那不是咱們關(guān)注的,只要記住,和方法有關(guān)的前前后后都是連接點(diǎn)。

package com.itsoft.action;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
/**
 * 
 * @author zxf
 * 演示aop測試類
 */
@Controller
public class UserAction {
 public void queryUsers(){
  System.out.println("查詢所有用戶【all users list】");
 }
 public static void main(String[] args) {
  ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("application-aop.xml");
  UserAction userAction = (UserAction)ctx.getBean("userAction");
  userAction.queryUsers();
  ctx.destroy();
 }
}
package com.itsoft;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
 * 
 * @author Administrator
 * 通過aop攔截后執(zhí)行具體操作
 */
@Aspect
@Component
public class LogIntercept {
 @Pointcut("execution(public * com.itsoft.action..*.*(..))")
 public void recordLog(){}
 @Before("recordLog()")
 public void before() {
  this.printLog("已經(jīng)記錄下操作日志@Before 方法執(zhí)行前");
 }
 @Around("recordLog()")
 public void around(ProceedingJoinPoint pjp) throws Throwable{
  this.printLog("已經(jīng)記錄下操作日志@Around 方法執(zhí)行前");
  pjp.proceed();
  this.printLog("已經(jīng)記錄下操作日志@Around 方法執(zhí)行后");
 }
 @After("recordLog()")
 public void after() {
  this.printLog("已經(jīng)記錄下操作日志@After 方法執(zhí)行后");
 }
 private void printLog(String str){
  System.out.println(str);
 }
}
<?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/context
  http://www.springframework.org/schema/context/spring-context-3.0.xsd
  http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  http://www.springframework.org/schema/aop 
  http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
 <context:annotation-config />
 <context:component-scan base-package="com.itsoft"/>
 <aop:aspectj-autoproxy />
</beans>

補(bǔ)充:spring aop的@Before,@Around,@After,@AfterReturn,@AfterThrowing的理解

1.AOP的基本概念

切面(Aspect) :通知(advice)和切入點(diǎn)(pointcut)共同組成了切面(aspect),時(shí)間、地點(diǎn)和要發(fā)生的“故事”。

可以從注解方式來理解,代碼如下。

@aspect為類上面的注解——切面

@pointcut(…)——切入點(diǎn)。為此類內(nèi)一個(gè)空方法上面的注解??梢园褦r截的地址表達(dá)式表示為方法簽名,利于使用起來方便。

@before@after等——通知。為此類下面的方法上面的注解。

三者在一塊組成一個(gè)切面。

@Aspect
public class ExampleAspect {
 @Pointcut("execution(* com.psjay.example.spring.aop.*.*(..))")
 public void aPointcut() {
 }
 @Before("aPointcut()")
 public void beforeAdvice() {
  System.out.println("before advice is executed!");
 }
}

連接點(diǎn)(Joinpoint) :程序能夠應(yīng)用通知的一個(gè)“時(shí)機(jī)”,這些“時(shí)機(jī)”就是連接點(diǎn),例如方法被調(diào)用時(shí)、異常被拋出時(shí)等等?!梢岳斫鉃楸籥op攔截的類或者方法就是連接點(diǎn)。

通知(Advice) :通知定義了切面是什么以及何時(shí)使用。描述了切面要完成的工作和何時(shí)需要執(zhí)行這個(gè)工作?!梢岳斫鉃楸蛔⒔庥蠤Before等advice注解的安全校驗(yàn)的方法,攔截了過來的請求要做什么邏輯的校驗(yàn)。

切入點(diǎn)(Pointcut) :通知定義了切面要發(fā)生的“故事”和時(shí)間,那么切入點(diǎn)就定義了“故事”發(fā)生的地點(diǎn),例如某個(gè)類或方法的名稱?!梢岳斫鉃榍忻媲邢蚰睦??是個(gè)類或者某層的包路徑。

目標(biāo)對象(Target Object) :即被通知的對象。

AOP代理(AOP Proxy) 在Spring AOP中有兩種代理方式,JDK動(dòng)態(tài)代理和CGLIB代理。默認(rèn)情況下,TargetObject實(shí)現(xiàn)了接口時(shí),則采用JDK動(dòng)態(tài)代理;反之,采用CGLIB代理。

織入(Weaving)把切面應(yīng)用到目標(biāo)對象來創(chuàng)建新的代理對象的過程,織入一般發(fā)生在如下幾個(gè)時(shí)機(jī):

(1)編譯時(shí):當(dāng)一個(gè)類文件被編譯時(shí)進(jìn)行織入,這需要特殊的編譯器才能做到,例如AspectJ的織入編譯器;

(2)類加載時(shí):使用特殊的ClassLoader在目標(biāo)類被加載到程序之前增強(qiáng)類的字節(jié)代碼;

(3)運(yùn)行時(shí):切面在運(yùn)行的某個(gè)時(shí)刻被織入,SpringAOP就是以這種方式織入切面的,原理是使用了JDK的動(dòng)態(tài)代理。

2 通知(Advice)類型的說明

@Before 前置通知(Before advice) :在某連接點(diǎn)(JoinPoint)——核心代碼(類或者方法)之前執(zhí)行的通知,但這個(gè)通知不能阻止連接點(diǎn)前的執(zhí)行。

為啥不能阻止線程進(jìn)入核心代碼呢?

因?yàn)锧Before注解的方法入?yún)⒉荒軅鱌roceedingJoinPoint,而只能傳入JoinPoint。

要知道從aop走到核心代碼就是通過調(diào)用ProceedingJionPoint的proceed()方法。

而JoinPoint沒有這個(gè)方法。

這里牽扯區(qū)別這兩個(gè)類:Proceedingjoinpoint 繼承了 JoinPoint 。

是在JoinPoint的基礎(chǔ)上暴露出 proceed 這個(gè)方法。proceed很重要,這個(gè)是aop代理鏈執(zhí)行的方法。

暴露出這個(gè)方法,就能支持 aop:around 這種切面(而其他的幾種切面只需要用到JoinPoint,這跟切面類型有關(guān)), 能決定是否走代理鏈還是走自己攔截的其他邏輯。

建議看一下 JdkDynamicAopProxy的invoke方法,了解一下代理鏈的執(zhí)行原理。

這樣你就能明白 proceed方法的重要性。

@After 后通知(After advice) :當(dāng)某連接點(diǎn)退出的時(shí)候執(zhí)行的通知(不論是正常返回還是異常退出)。

@AfterReturning 返回后通知(After return advice) :在某連接點(diǎn)正常完成后執(zhí)行的通知,不包括拋出異常的情況。

@Around 環(huán)繞通知(Around advice) :包圍一個(gè)連接點(diǎn)的通知,類似Web中Servlet規(guī)范中的Filter的doFilter方法。

可以在方法的調(diào)用前后完成自定義的行為,也可以選擇不執(zhí)行。

這時(shí)aop的最重要的,最常用的注解。

用這個(gè)注解的方法入?yún)鞯氖荘roceedingJionPoint pjp,可以決定當(dāng)前線程能否進(jìn)入核心方法中——通過調(diào)用pjp.proceed();

@AfterThrowing 拋出異常后通知(After throwing advice) : 在方法拋出異常退出時(shí)執(zhí)行的通知。

3 advice(通知)注解的執(zhí)行先后順序

這里說下簡單情況——針對一個(gè)方法只被一個(gè)aspect類攔截時(shí),aspect類內(nèi)部的 advice 將按照以下的順序進(jìn)行執(zhí)行情況如下:

解釋:執(zhí)行到核心業(yè)務(wù)方法或者類時(shí),會先執(zhí)行AOP。在aop的邏輯內(nèi),先走@Around注解的方法。

然后是@Before注解的方法,然后這兩個(gè)都通過了,走核心代碼,核心代碼走完,無論核心有沒有返回值,都會走@After方法。

然后如果程序無異常,正常返回就走@AfterReturn,有異常就走@AfterThrowing。

復(fù)雜的同一個(gè)方法被多個(gè)Aspect類攔截請參看博文:Spring AOP @Before @Around @After 等 advice 的執(zhí)行順序。

4 在aop中校驗(yàn)不通過如何不讓程序進(jìn)入核心代碼?

通過aop中注解的執(zhí)行的先后順序我們知道,校驗(yàn)發(fā)生在核心代碼前面的只剩下兩個(gè)——@Before,@Around。

@Before : 這個(gè)注解只有在異常時(shí)才不會走核心方法——連接點(diǎn)。正常@Before無法阻止當(dāng)前線程進(jìn)入連接點(diǎn)。

@Around : 這個(gè)注解在連接點(diǎn)前后執(zhí)行。并且注解的方法傳入的ProceedingJionPoint 類中封裝的代理方法proceed()可以讓當(dāng)前線程從aop方法轉(zhuǎn)到連接點(diǎn)——核心代碼方法。

所以一般我們用這個(gè)注解,如果aop的安全校驗(yàn)不通過,則不調(diào)用proceed()方法,就永遠(yuǎn)不會進(jìn)入連接點(diǎn)。

除此外,要注意除了Around注解的方法可以傳ProceedingJionPoint 外,別的幾個(gè)都不能傳這個(gè)類。

但是普通的數(shù)據(jù)類型是不限制的。

注解的方法的返回值也不限制,可以自由限制。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教。

相關(guān)文章

  • SpringCloud中NacosNamingService的作用詳解

    SpringCloud中NacosNamingService的作用詳解

    這篇文章主要介紹了SpringCloud中NacosNamingService的作用詳解,NacosNamingService類完成服務(wù)實(shí)例注冊,撤銷與獲取服務(wù)實(shí)例操作,NacosNamingService初始化采用單例模式,使用反射生成,需要的朋友可以參考下
    2023-11-11
  • Java @RequestMapping注解功能使用詳解

    Java @RequestMapping注解功能使用詳解

    通過@RequestMapping注解可以定義不同的處理器映射規(guī)則,下面這篇文章主要給大家介紹了關(guān)于SpringMVC中@RequestMapping注解用法的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • java JTree JCheckBox樹復(fù)選框詳解

    java JTree JCheckBox樹復(fù)選框詳解

    這篇文章主要為大家詳細(xì)介紹了java JTree JCheckBox樹復(fù)選框的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • SpringBoot從2.7.x 升級到3.3注意事項(xiàng)

    SpringBoot從2.7.x 升級到3.3注意事項(xiàng)

    從SpringBoot 2.7.x升級到3.3涉及多個(gè)重要變更,特別是因?yàn)?nbsp;Spring Boot 3.x 系列基于 Jakarta EE 9,而不再使用 Java EE,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-09-09
  • Mybatis下的SQL注入漏洞原理及防護(hù)方法解析

    Mybatis下的SQL注入漏洞原理及防護(hù)方法解析

    SQL 注入是發(fā)生在 Web 程序中數(shù)據(jù)庫層的安全漏洞,是網(wǎng)站存在最多也是最簡單的漏洞,在實(shí)際項(xiàng)目中,即使使用了 Mybatis 框架,但仍然有可能因?yàn)榫幋a人員安全意識不足而導(dǎo)致 SQL 注入問題,這篇文章主要介紹了Mybatis下的SQL注入漏洞原理及防護(hù)方法?,需要的朋友可以參考下
    2022-11-11
  • Java模擬qq軟件的詳細(xì)過程

    Java模擬qq軟件的詳細(xì)過程

    這篇文章主要為大家詳細(xì)介紹了用Java實(shí)現(xiàn)模擬QQ,實(shí)現(xiàn)了消息通信+登陸界面美化,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • redis深入淺出分布式鎖實(shí)現(xiàn)下篇

    redis深入淺出分布式鎖實(shí)現(xiàn)下篇

    在單體應(yīng)用中,如果我們對共享數(shù)據(jù)不進(jìn)行加鎖操作,會出現(xiàn)數(shù)據(jù)一致性問題,我們的解決辦法通常是加鎖。下面我們一起聊聊使用redis來實(shí)現(xiàn)分布式鎖
    2022-08-08
  • Spring Security基于json登錄實(shí)現(xiàn)過程詳解

    Spring Security基于json登錄實(shí)現(xiàn)過程詳解

    這篇文章主要介紹了Spring Security基于json登錄實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • 基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過程解析

    基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過程解析

    這篇文章主要介紹了基于springboot實(shí)現(xiàn)整合shiro實(shí)現(xiàn)登錄認(rèn)證以及授權(quán)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • springMVC返回復(fù)雜的json格式數(shù)據(jù)方法

    springMVC返回復(fù)雜的json格式數(shù)據(jù)方法

    下面小編就為大家分享一篇springMVC返回復(fù)雜的json格式數(shù)據(jù)方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03

最新評論

东方市| 天水市| 确山县| 永济市| 黑水县| 肇州县| 崇义县| 尼勒克县| 和硕县| 阿坝| 偏关县| 万宁市| 牡丹江市| 攀枝花市| 宣化县| 泸西县| 聂拉木县| 孝感市| 普格县| 修文县| 厦门市| 连江县| 名山县| 浦东新区| 交城县| 舞钢市| 岱山县| 广宁县| 大化| 湖口县| 平陆县| 肥西县| 昭平县| 绥滨县| 莎车县| 双牌县| 施甸县| 大连市| 滨州市| 屏山县| 麻栗坡县|