中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

北京自助模板建站黑馬程序員培訓機構在哪

北京自助模板建站,黑馬程序員培訓機構在哪,貴港哪里有網站建設推廣,wordpress 郵件通知IOC AOP 一、 分層解耦 內聚: 軟件中各個功能模塊內部的功能聯(lián)系 耦合: 衡量軟件中各個層/模塊之間的依賴、關聯(lián)的程度 軟件設計原則:高內聚、低耦合 ? 控制反轉:Inversion Of Control,簡稱IOC。對象的創(chuàng)建控制權由程序自身轉移到…

IOC AOP
一、 分層解耦
內聚: 軟件中各個功能模塊內部的功能聯(lián)系
耦合: 衡量軟件中各個層/模塊之間的依賴、關聯(lián)的程度
軟件設計原則:高內聚、低耦合
? 控制反轉:Inversion Of Control,簡稱IOC。對象的創(chuàng)建控制權由程序自身轉移到外部(容器),這種思想成為控制反轉

? 依賴注入:Dependency Injection,簡稱DI。容器為應用程序提供運行時,所依賴的資源,稱為依賴注入。

? Bean對象: IOC容器中創(chuàng)建、管理的對象,稱為bean
1.1 IOC - 控制反轉 詳細
把某個對象交給IOC容器管理,需要添加如下注解之一:
在這里插入圖片描述
聲名bean的時候,可以通過value屬性指定bean的名字,如果沒有指定,默認是類名首字母小寫

使用以上四個注解都可以生命bean,但是在Springboot集成web開發(fā)中,聲名控制器bean只能用@Controller

bean的四大注解想要生效,需要被組件掃描注解@ComponentScan掃描

@ComponentScan注解雖然沒有顯示配置,但是實際上已經包含在了啟動類生命注解@SpringBootApplication中,默認掃描的范圍是啟動類所在包及其子包

如下包名是從“java”包后開始的,但是下面這種不推薦,我們希望的是按照Spring的規(guī)范,將包設置在啟動類所在包及其子包

@ComponentScan({"dao","com.zhangjingqi"})

1.2 DI - 依賴注入 詳解
@Autowired 注解,默認是按照類型進行的,如果存在多個相同的bean,會報錯。

EmpServiceA 實現(xiàn) EmpService類,EmpServiceB 實現(xiàn) EmpService類,我們在某個地方注入EmpService對象時便會出現(xiàn)注入錯誤。

解決方案

@Primary 設置bean的優(yōu)先級
? 如果我們想要哪個bean填入容器,可以在類名之上添加@Primary

@Qualifier 指定bean的名字

   @Qualifier("empServiceA")@Autowiredprivate EmpService empService;

@Resource 按照名稱注入

@Autowired 注解默認按照類型注入,@Resource默認按照類名進行注入

   @Resource(name = "empServiceB")private EmpService empService;

二、AOP
2.1 了解
Spring的第二大核心,第一大核心是IOC

AOP:面向切面編程、面向方面編程,其實就是面向特定方法編程

實現(xiàn):

**動態(tài)代理是面向切面編程最主流的實現(xiàn)。**而SpringAOP是Spring框架的高級技術,目的是在管理bean對象的過程中,主要通過底層的動態(tài)代理機制,對特定的方法進行編程

為什么要面向方法編程?

? 場景:案例部分功能運行較慢,定位執(zhí)行耗時較長的業(yè)務方法,此時需要統(tǒng)計每一個業(yè)務方法的執(zhí)行耗時,找到耗時較長的業(yè)務進行優(yōu)化

? 按照之前的方式,就是在方法開始前和開時候分別獲取一個時間,兩個時間相減就是執(zhí)行耗時,但是這種方式是非常繁瑣的
————————————————
版權聲明:本文為CSDN博主「我愛布朗熊」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權協(xié)議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_51351637/article/details/130779252二、AOP

2.1 了解
Spring的第二大核心,第一大核心是IOC

AOP:面向切面編程、面向方面編程,其實就是面向特定方法編程

實現(xiàn):

**動態(tài)代理是面向切面編程最主流的實現(xiàn)。**而SpringAOP是Spring框架的高級技術,目的是在管理bean對象的過程中,主要通過底層的動態(tài)代理機制,對特定的方法進行編程

為什么要面向方法編程?

? 場景:案例部分功能運行較慢,定位執(zhí)行耗時較長的業(yè)務方法,此時需要統(tǒng)計每一個業(yè)務方法的執(zhí)行耗時,找到耗時較長的業(yè)務進行優(yōu)化

? 按照之前的方式,就是在方法開始前和開時候分別獲取一個時間,兩個時間相減就是執(zhí)行耗時,但是這種方式是非常繁瑣的
在這里插入圖片描述
如果我們基于AOP,面向方法編程,我們可以做到在不改動原始方法的基礎上,來針對原始的方法進行編程,可以是對原始方法功能的增強,也可以改變原始方法的功能

比如我們現(xiàn)在要統(tǒng)計方法的耗時,我們只需要定義一個模板方法,將公共的代碼定義在模板方法中

原始業(yè)務方法在這里指的是需要統(tǒng)計執(zhí)行耗時的業(yè)務方法。而這樣面向一個或者多個方法進行編程,就稱為面向切面編程

比如我們調用list()方法,此時并不會直接執(zhí)行原始的list方法,而是自動的去執(zhí)行模板方法。

模板中所定義的代碼邏輯其實是創(chuàng)建出來的代理對象方法中的邏輯
在這里插入圖片描述
2.2 快速入門 - AOP 開發(fā)步驟
需求:統(tǒng)計各個業(yè)務層方法執(zhí)行耗時

2.2.1 Maven依賴

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2.2.2 代碼實現(xiàn)
針對于特定方法根據(jù)業(yè)務需要進行編程

@Slf4j
@Component //交給容器IOC進行管理
@Aspect //加上這個注解表示不是一個普通的類,而是一個AOP類,在此類中定義模板方法
public class TimeAspect {//  參數(shù)是一個表達式,表示針對哪些特定方法進行編程
//  com.zhangjingqi.service 包名
//  第一個*代表任意返回值 第二個*代表類名或者接口名  第三個*代表方法名@Around("execution(* com.zhangjingqi.service.*.*(..))") //切入點表達式public Object recordTime(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {long begin = System.currentTimeMillis();//      result 原始方法執(zhí)行返回值Object result = proceedingJoinPoint.proceed();//調用原始方式運行long end = System.currentTimeMillis();//      proceedingJoinPoint.getSignature() 獲取方法的簽名,我們就知道是哪個方法了
//      如: List com.zhangjingqi.service.impl.DeptServiceImpl.list()執(zhí)行耗時:239mslog.info(proceedingJoinPoint.getSignature() + "執(zhí)行耗時:{}ms", end - begin);//      原始方法的返回值我們需要返回回去return result;}
}

2.2.3 AOP 應用場景及優(yōu)勢
應用場景

記錄操作日志
權限控制
事務管理
在這里插入圖片描述
優(yōu)勢

代碼無侵入
減少重復代碼
提高開發(fā)效率
維護方便
2.3 核心概念
2.3.1 連接點 - JoinPoint
連接點:JoinPoint,可以被AOP控制的方法(暗含方法執(zhí)行時的相關信息)

通知:Advice,指那些重讀的邏輯,也就是共性功能(最終體現(xiàn)為一個方法)

切入點:PointCut,匹配連接點的條件,通知僅會在切入點方法執(zhí)行時被應用(就是實際被AOP控制的方法)

我們通常會使用下面的切入點表達式來描述切入點

@Around("execution(* com.zhangjingqi.service.*.*(..))") 

切面:Aspect,描述通知與切入點的對應關系(通知+切入點),被@Aspect注解修飾的類我們一般稱為切面類

目標對象:Target,通知所應用的對象。

在這里插入圖片描述
2.3.2 AOP執(zhí)行流程
通知如何與目標對象結合在一起對目標對象中的方法進行功能增強的?

? ①SpringAOP是基于動態(tài)代理技術來實現(xiàn)的。程序運行的時候會自動的基于動態(tài)代理技術為目標對象生成一個對應的代理對象。

? ② 在代理對象中就會對目標對象中的原始方法進行功能的增強。

? 如何來增強的?增強的邏輯是什么樣子的?

? 其實就是我們的通知

? ③最終在Spring容器中注入的是代理對象,調用的方法也是代理對象中的對應方法

在這里插入圖片描述
2.4 通知
2.4.1 通知類型
@Around:環(huán)繞通知,此注解標注的通知方法在目標方法前、后都被執(zhí)行,出現(xiàn)異常后后置代碼不會執(zhí)行。(因為原始方法出現(xiàn)異常了)
@Before:前置通知,此注解標注的通知方法在目標方法前被執(zhí)行
@After:后置通知,此注解標注的通知方法在目標方法后被執(zhí)行,無論是否有異常都會執(zhí)行
@AfterReturning:返回后通知,此注解標注的通知方法在目標方法后被執(zhí)行,有異常不會執(zhí)行
@AfterThrowing:異常后通知,此注解標注的通知方法在發(fā)生異常后執(zhí)行

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Slf4j
@Component
@Aspect
public class MyAspect1 {//前置通知@Before("execution(* com.zhangjingqi.service.*.*(..))")public void before(JoinPoint joinPoint) {log.info("before ...");}//環(huán)繞通知@Around("execution(* com.zhangjingqi.service.*.*(..))")public Object around(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {log.info("around before ...");//調用目標對象的原始方法執(zhí)行Object result = proceedingJoinPoint.proceed();//原始方法如果執(zhí)行時有異常,環(huán)繞通知中的后置代碼不會在執(zhí)行了log.info("around after ...");return result;}//后置通知@After("execution(* com.zhangjingqi.service.*.*(..))")public void after(JoinPoint joinPoint) {log.info("after ...");}//返回后通知(程序在正常執(zhí)行的情況下,會執(zhí)行的后置通知)@AfterReturning("execution(* com.zhangjingqi.service.*.*(..))")public void afterReturning(JoinPoint joinPoint) {log.info("afterReturning ...");}//異常通知(程序在出現(xiàn)異常的情況下,執(zhí)行的后置通知)@AfterThrowing("execution(* com.zhangjingqi.service.*.*(..))")public void afterThrowing(JoinPoint joinPoint) {log.info("afterThrowing ...");}
}

注意事項

@Around環(huán)繞通知需要自己調用ProceedingJoinPoint.proceed()來執(zhí)行原始方法,其他通知不需要考慮原始方法的執(zhí)行

@Around環(huán)繞通知的方法的返回值,必須指定為Object,來接收原始方法的返回值

? 如果不return,在調用這個方法的地方時拿不到返回值的

對切入點表達式進行抽取

//   生命切入點表達式的注解,切點@Pointcut("execution(* com.zhangjingqi.service.*.*(..))")private void pt(){}//前置通知@Before("pt()")public void before(JoinPoint joinPoint) {log.info("before ...");}

其他類中也可以進行抽取,只需要定位到切入點表達式的位置即可。

@Slf4j
@Component
@Aspect
public class MyAspect2 {
//引用MyAspect1切面類中的切入點表達式
@Before("com.zhangjingqi.aspect.MyAspect1.pt()")
public void before(){
log.info("MyAspect2 -> before ...");}
}

2.4.2 通知順序
? 當有多個切面的切入點都匹配到了目標方法,目標方法運行,多個通知方法都會被執(zhí)行。

? 下面研究多個切面類的通知順序。同個切面類的通知順序不再研究

不同切面類中,默認按照切面類的類名字母排序
? 目標方法前的通知方法:字母排名靠前的先執(zhí)行

? 目標方法后的通知方法:字母排名靠前的后執(zhí)行

使用@Order(數(shù)字)加在切面類上來控制順序
2.5 切入點表達式
切入點表達式:描述切入點方法的一種表達式
作用:主要用來決定項目中哪些方法需要加入通知
常見形式
? execution(…):根據(jù)方法的簽名來匹配

? @annotation(…):根據(jù)注解匹配

2.5.1 execution
? 主要根據(jù)方法的返回值、包名、類名、方法名、方法參數(shù)等信息來匹配

? 下面來描述的時候,可以基于接口。也可以基于實現(xiàn)類

execution(訪問修飾符? 返回值 包名.類名.?方法名(方法參數(shù)) throws 異常?)

? 其中?表示可省略的部分

訪問修飾符:可省略,比如public、protected
包名.類名:可省略,但是不建議
throws 異常:可省略(注意是方法上聲明拋出的異常,不是實際拋出的異常)
2.5.1.1 execution通配符
*:單個獨立的任意符號,可以匹配任意返回值、包名、類名、方法名、方法參數(shù)等信息來匹配

? 此案例表示返回值人任意,二級包任意,類或接口任意,方法參數(shù)任意但是有且只有一個

execution(* com.*.service.*.update(*)

匹配類名以Service結尾,方法以delete開頭的方法

execution(void
com.itheima.service.impl.*Service.delete*(java.lang.Integer)
)

…:多個連續(xù)的任意符號,可以通配任意層級的包,或者任意類型、任意個數(shù)的參數(shù)

? 層級包任意,方法的參數(shù)任意

execution(* com.zhangjingqi..DeptService.*(..)

返回值任意,方法名任意,方法參數(shù)任意

execution(* *(..)

2.5.1.2 execution表達式案例

@Pointcut("execution(* com.zhangjingqi.service.*.*(..))")

省略異常

execution(public void
com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer)
)

省略方法訪問修飾符

參數(shù)是全類名

execution(void
com.itheima.service.impl.DeptServiceImpl.delete(java.lang.Integer)
)

使用"…"省略包名

execution(public void  com..DeptServiceImpl.delete(java.lang.Integer))

省略包名類名
? 指定方法名。

? 不建議將包名和方法名省略。一旦省略,將表達式的范圍擴大,一是影響匹配的效率,而是可能匹配到其他不需要的方法

execution(public void  delete(java.lang.Integer))

匹配所有的方法
? 此時表示匹配DeptServiceImpl類中的所有方法

execution(public void  com..DeptServiceImpl.*(java.lang.Integer))

使用 且(&&)、或(||)、非(!) 來組合比較復雜的切入點表達式

execution(* com.zhangjingqi.service.DeptService.list(..)) ||
execution(* com.zhangjingqi.service.DeptService.delete(..))

2.5.1.3 切入點表達式建議
所有業(yè)務方法名在命名時盡量規(guī)范,方便切入點快速匹配。
? 如查詢方法find開頭,更新類方法update開頭

描述切入點方法通?;诮涌诿枋?#xff0c;而不是直接描述實現(xiàn)類,增強拓展性

在滿足業(yè)務需要的前提下,盡量縮小切入點的匹配范圍

? 包名匹配進行不使用“…”,使用“*”匹配單個包

2.5.2 @annotation
用于匹配標識有特定注解的方法

@Before("@annotation(com.zhangjingqi.anno.MyLog)")

簡化下列表達式

execution(* com.zhangjingqi.service.DeptService.list(..)) ||
execution(* com.zhangjingqi.service.DeptService.delete(..))

實現(xiàn)步驟

編寫自定義注解

在業(yè)務類要做為連接點的方法上添加自定義注解

創(chuàng)建自定義注解類

@Retention(RetentionPolicy.RUNTIME)//描述注解什么時候生效的:運行時有效
@Target(ElementType.METHOD)//當前注解可以作用在哪些地方
public @interface MyLog {
}

添加自定義注解

@Override
@MyLog //自定義注解(表示:當前方法屬于目標方法)
public List<Dept> list() { ... }@Override
@MyLog //自定義注解(表示:當前方法屬于目標方法)
public void delete(Integer id) { ... }

切面類

@Slf4j
@Component
@Aspect
public class MyAspect6 {
//針對list方法、delete方法進行前置通知和后置通知
//前置通知
@Before("@annotation(com.zhangjingqi.anno.MyLog)")public void before(){log.info("MyAspect6 -> before ...");//后置通知
@After("@annotation(com.zhangjingqi.anno.MyLog)")public void after(){log.info("MyAspect6 -> after ...");}
}

2.5.3 切入點表達式總結
execution切入點表達式
? 根據(jù)我們所指定的方法的描述信息來匹配切入點方法,這種方式也是最為常用的一種方式

? 如果我們要匹配的切入點方法的方法名不規(guī)則,或者有一些比較特殊的需求,通過

? execution切入點表達式描述比較繁瑣

annotation 切入點表達式
? 基于注解的方式來匹配切入點方法。這種方式雖然多一步操作,我們需要自定義一個注解,但

? 是相對來比較靈活。我們需要匹配哪個方法,就在方法上加上對應的注解就可以了

2.6 連接點
? 被AOP控制的方法,目標對象中所有的方法都可以被AOP控制,在Spring AOP中又特制方法的執(zhí)行
在這里插入圖片描述
在Spring中用JoinPoint抽象了連接點,用它可以獲得方法執(zhí)行時的相關信息,如目標類名、方法類名、方法參數(shù)等
? 對于@Around通知,獲取連接點信息只能用ProceedingJoinPoint
在這里插入圖片描述
? 對于其他四種通知,獲取連接點信息只能使用JoinPoint,它是ProceedingJoinPoint父類型

在這里插入圖片描述
對于@Around通知,為什么獲取連接點信息只能用ProceedingJoinPoint?

在Spring AOP中,@Around通知是最為強大和靈活的通知類型,它可以決定是否執(zhí)行連接點,以及如何處理連接點返回的結果。因此,@Around通知需要通過ProceedingJoinPoint參數(shù)來獲取連接點信息。

? ProceedingJoinPoint是JoinPoint的子類,同時也是JoinPoint的擴展版本。JoinPoint表示連接點,也就是被Advice修飾的方法。而ProceedingJoinPoint除了表示連接點外,還具有一個proceed()方法,該方法是執(zhí)行目標方法的關鍵。在@Before和@After通知中,JoinPoint足以滿足需要,因為它們只需要獲取連接點信息即可,不需要執(zhí)行目標方法。但在@Around中,除了獲取連接點信息,還需要控制目標方法的執(zhí)行,因此需要用到ProceedingJoinPoint。

? 在@Around通知中,可以通過ProceedingJoinPoint的proceed()方法,手動控制目標方法的執(zhí)行。例如,可以在proceed()方法前后進行一些預處理或后處理。同時,ProceedingJoinPoint還提供了一些其他的工具方法,例如getArgs()獲取目標方法參數(shù),getSignature()獲取目標方法簽名等,這些方法在編寫@Around通知時也非常有用。

http://www.risenshineclean.com/news/36409.html

相關文章:

  • 學生做的網站成品網絡客服
  • 西安微網站制作網上廣告宣傳怎么做
  • 畢業(yè)設計網站成品百度接單平臺
  • 做B2C獨立網站的話需要做海外倉嗎人際網絡營銷2900
  • 高端電子網站建設谷歌官方seo入門指南
  • 子目錄 獨立的網站網上怎么發(fā)布廣告
  • 網站源碼破解版網站關鍵詞優(yōu)化排名外包
  • 金融投資公司網站模板網站工具查詢
  • 江蘇省城鄉(xiāng)建設官網站免費私人網站建設
  • wordpress文章全部刪除優(yōu)化seo深圳
  • 不建網站如何做淘寶客社交網絡推廣方法
  • 江陰外貿網站制作福州網站建設
  • 修改網站圖標卡一卡二卡三入口2021
  • 浙里建官方網站百度指數(shù)的主要功能有
  • 手機端網站開發(fā)長沙網站seo方法
  • 美食網站的設計與制作友情鏈接方面pr的選擇應該優(yōu)先選擇的鏈接為
  • 怎樣做原創(chuàng)短視頻網站百度關鍵詞工具
  • 網站建設網站推廣公司怎么建立自己的網站
  • 百度關鍵詞怎么做排名愛站工具seo綜合查詢
  • 公眾微信綁定網站帳號安卓aso優(yōu)化排名
  • 國外的工業(yè)設計網站seo就業(yè)前景如何
  • html5網站動效怎么做百度一下官網首頁百度一下百度
  • 什么做網站推廣百度售后服務電話
  • 鄒城網站建設搜索引擎營銷的英文簡稱
  • 銷售類電商網站如何做優(yōu)化友情鏈接聯(lián)盟
  • 重慶市建設工程信息網的信用信息發(fā)布平臺廈門seo網絡推廣
  • 基于目的地的o2o旅游電子商務網站開發(fā)設計畢業(yè)設計公眾號推廣平臺
  • 防城港做網站的培訓機構有哪些
  • 深圳做微信網站建設公司網站制作費用
  • 百度做網站嗎中國搜索引擎排名2021