日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
你了解Spring AOP的這個(gè)技能點(diǎn)嗎?有什么應(yīng)用場(chǎng)景?

環(huán)境:Spring5.3.23

10多年的黃埔網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。營銷型網(wǎng)站建設(shè)的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整黃埔建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)從事“黃埔網(wǎng)站設(shè)計(jì)”,“黃埔網(wǎng)站推廣”以來,每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

1. 介紹

今天看Spring文檔看到這么一個(gè)知識(shí)點(diǎn)《Control Flow Pointcuts》都不好翻譯

官方原文:

Spring control flow pointcuts are conceptually similar to AspectJ cflow pointcuts, although less powerful. (There is currently no way to specify that a pointcut runs below a join point matched by another pointcut.) A control flow pointcut matches the current call stack. For example, it might fire if the join point was invoked by a method in the com.mycompany.web package or by the SomeCaller class. Control flow pointcuts are specified by using the org.springframework.aop.support.ControlFlowPointcut class.

大意:Spring控制流切入點(diǎn)在概念上類似于aspectj cflow切入點(diǎn),盡管功能不那么強(qiáng)大。(目前還沒有辦法指定一個(gè)切入點(diǎn)在與另一個(gè)切入點(diǎn)匹配的連接點(diǎn)下面運(yùn)行。)控制流切入點(diǎn)與當(dāng)前調(diào)用堆棧匹配。例如,如果連接點(diǎn)由com.mycompany.web包中的方法或someecaller類調(diào)用,則可能會(huì)觸發(fā)該連接點(diǎn)??刂屏髑腥朦c(diǎn)是通過使用org.springframework.aop.support.ControlFlowPointcut類指定的。

其實(shí)看完這個(gè),可能你還是不懂什么意思,接下來我們來跑一個(gè)實(shí)例,就能明白撒意思了。

2. Control Flow實(shí)例

準(zhǔn)備幾個(gè)方法嵌套調(diào)用的類

static class PersonDAO {
  public void save(String name) {
    System.out.println("PersonDAO save method invoke...") ;
  }
}
static class PersonService {
  private PersonDAO dao ;
  public PersonService(PersonDAO dao) {
    this.dao = dao ;
  }
  public void save(String name) {
    System.out.println("PersonService save method inovke...") ;
    this.dao.save(name) ;
  }
}


static class PersonManager {
  private PersonService ps ;
  public void setPs(PersonService ps) {
    this.ps = ps ;
  }
  public void index(String name) {
    System.out.println("PersonManager index method invoke...") ;
    this.ps.save(name) ;
  }
}

上面的類及方法調(diào)用非常簡(jiǎn)單:PersonManager ---> PersonService ---> PersonDAO。接下來是通過編程的方式創(chuàng)建PersonService代理對(duì)象。

// 實(shí)例化上面的類
PersonDAO dao = new PersonDAO() ;
PersonService target = new PersonService(dao) ;


PersonManager pm = new PersonManager() ;


Class clazz = PersonManager.class ;
String methodName = "index" ;
// 定義切入點(diǎn)
ControlFlowPointcut pointcut = new ControlFlowPointcut(clazz, methodName) ;
// 定義通知
MethodInterceptor logInterceptor = invocation -> {
  System.out.println("before log...") ;
  Object ret = invocation.proceed() ;
  System.out.println("after log...") ;
  return ret ;
} ;
// 定義切面


DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, logInterceptor) ;
// 通過ProxyFactory創(chuàng)建代理對(duì)象,創(chuàng)建的是PersonService對(duì)象的代理
ProxyFactory factory = new ProxyFactory(target) ;
factory.addAdvisor(advisor) ;
// 基于CGLIB生成代理
factory.setProxyTargetClass(true) ;
PersonService ps = (PersonService) factory.getProxy() ;


pm.setPs(ps) ;


pm.index("張三") ;

控制臺(tái)輸出

PersonManager index method invoke...
before log...
PersonService save method inovke...
PersonDAO save method invoke...
after log...

從輸出的結(jié)果發(fā)現(xiàn),在PersonService#save方法之前之前和之后分別打印了日志信息。原理是什么呢?這里我們需要先看ControlFlowPointcut 切入點(diǎn)是如何工作的。

ControlFlowPointcut核心方法

這里只列出了幾個(gè)重要的方法,在spring中只支持方法級(jí)別的攔截。

public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher, Serializable {
  private final Class clazz;
  @Nullable
  private final String methodName;
  // 對(duì)應(yīng)類級(jí)別的匹配全部返回true,就是都匹配
  @Override
  public boolean matches(Class clazz) {
    return true;
  }
  // 方法匹配,直接true
  @Override
  public boolean matches(Method method, Class targetClass) {
    return true;
  }
  // 這里是關(guān)鍵,只有isRuntime返回了true才有可能調(diào)用下面3個(gè)參數(shù)的matches方法
  @Override
  public boolean isRuntime() {
    return true;
  }
  // 該方法的調(diào)用需要上面2個(gè)參數(shù)的matches方法返回true且isRuntime方法也返回true才會(huì)調(diào)用這里
  @Override
  public boolean matches(Method method, Class targetClass, Object... args) {
    // 遍歷當(dāng)前線程的執(zhí)行棧情況(也就是當(dāng)前方法的調(diào)用棧情況)
    for (StackTraceElement element : new Throwable().getStackTrace()) {
      // 這里就開始判斷當(dāng)前執(zhí)行的類是否與給定的類相同 && 當(dāng)前設(shè)置的methodName為空或者當(dāng)前棧執(zhí)行的方法名與給定的方法名相同
      if (element.getClassName().equals(this.clazz.getName()) &&
          (this.methodName == null || element.getMethodName().equals(this.methodName))) {
        // 最終這里只有返回了true,我們上面的通知MethodInterceptor才會(huì)被執(zhí)行
        return true;
      }
    }
    return false;
  }
}

有了上面源碼的分析后,我們?cè)賮砜纯瓷厦娴氖纠a:

// 指明要匹配的類
Class clazz = PersonManager.class ;
// 指明要匹配的方法名
String methodName = "index" ;
/** 
 * 將傳入到切入點(diǎn)中;而在該切入點(diǎn)的matches方法中進(jìn)行了判斷,
 * 整個(gè)執(zhí)行的線程棧中的所有類及方法是否與這里給定的相同,
 * 只有相同了攔截器才能執(zhí)行
 */
ControlFlowPointcut pointcut = new ControlFlowPointcut(clazz, methodName) ;

分析到這你應(yīng)該知道這個(gè)Control Flow有撒用了吧,總結(jié):

Control Flow就是用來判斷當(dāng)前執(zhí)行的線程棧中(所有方法的調(diào)用)是否與你給定的類及方法匹配,只有匹配了才能執(zhí)行我們的增強(qiáng)(通知)代碼。

簡(jiǎn)單說:我PersonService想監(jiān)控PersonManager中的index方法是否調(diào)用了我。

官方有這段說明:

Dynamic pointcuts are costlier to evaluate than static pointcuts. They take into account method arguments as well as static information. This means that they must be evaluated with every method invocation and that the result cannot be cached, as arguments will vary.

The main example is the control flow pointcut.

大意:與靜態(tài)快捷方式相比,動(dòng)態(tài)快捷方式的評(píng)估成本更高。它們會(huì)考慮方法參數(shù)和靜態(tài)信息。這意味著每次調(diào)用方法時(shí)都必須對(duì)其進(jìn)行評(píng)估,而且由于參數(shù)會(huì)發(fā)生變化,因此無法緩存評(píng)估結(jié)果??刂屏骺旖莘绞骄褪且粋€(gè)主要的例子。

3. Control Flow性能

同樣來自官方說明:

Control flow pointcuts are significantly more expensive to evaluate at runtime than even other dynamic pointcuts. In Java 1.4, the cost is about five times that of other dynamic pointcuts.

大意:與其他動(dòng)態(tài)切入點(diǎn)相比,控制流切入點(diǎn)在運(yùn)行時(shí)評(píng)估的成本要高得多。在Java1.4中,成本大約是其他動(dòng)態(tài)切入點(diǎn)的五倍。

知道了Control Flow怎么一回事,那它有什么使用場(chǎng)景嗎?有使用過的還望能分享下,歡迎大家留言討論。圖片


新聞標(biāo)題:你了解Spring AOP的這個(gè)技能點(diǎn)嗎?有什么應(yīng)用場(chǎng)景?
標(biāo)題URL:http://m.5511xx.com/article/ccodjhc.html