<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      VonaJS AOP編程大殺器:外部切面

      在VonaJS框架中,AOP編程包括三方面:控制器切面內(nèi)部切面外部切面。

      1. 控制器切面: 為 Controller 方法切入邏輯,包括:Middleware、Guard、Interceptor、Pipe和Filter
      2. 內(nèi)部切面: 在 Class 內(nèi)部,為任何 Class 的任何方法切入邏輯,包括:AOP Method和魔術(shù)方法
      3. 外部切面: 在不改變 Class 源碼的前提下,從外部為任何 Class 的任何方法切入邏輯

      VonaJS中的外部切面,可以類比于Spring Boot中的AOP切面AOP織入概念。VonaJS的外部切面不需要什么前置通知、后置通知、異常通知環(huán)繞通知,只需提供一個(gè)同名方法就可以了。之所以可以這么簡(jiǎn)潔,是因?yàn)槭褂昧搜笫[圈模型。

      此外,VonaJS的外部切面支持完整的類型推斷與智能代碼提示,開(kāi)發(fā)體感比Spring Boot優(yōu)雅太多。

      下面,我們就來(lái)考察一下VonaJS的外部切面到底是個(gè)什么樣?為什么可以成為AOP編程的??大殺器??

      創(chuàng)建目標(biāo)Class

      可以針對(duì)任何 Class 實(shí)現(xiàn)外部切面。下面,以 Service 為例,在模塊 demo-student 中創(chuàng)建一個(gè) Service test,代碼如下:

      @Service()
      export class ServiceTest extends BeanBase {
        private _name: string;
      
        protected __init__() {
          this._name = '';
        }
      
        protected async __dispose__() {
          this._name = '';
        }
      
        get name() {
          return this._name;
        }
      
        set name(value) {
          this._name = value;
        }
      
        actionSync(a: number, b: number) {
          return a + b;
        }
      
        async actionAsync(a: number, b: number) {
          return Promise.resolve(a + b);
        }
      }
      

      創(chuàng)建外部切面

      接下來(lái),創(chuàng)建一個(gè)外部切面log,為 Class ServiceTest的屬性和方法分別提供擴(kuò)展邏輯

      1. Cli命令

      $ vona :create:bean aop log --module=demo-student
      

      2. 菜單命令

      右鍵菜單 - [模塊路徑]: Vona Aspect/Aop
      

      AOP定義

      import { BeanAopBase } from 'vona';
      import { Aop } from 'vona-module-a-aspect';
      
      @Aop({ match: 'demo-student.service.test' })
      export class AopLog extends BeanAopBase {}
      
      • @Aop: 此裝飾器用于實(shí)現(xiàn)外部切面
      • match: 用于將 Class AopLog與 Class ServiceTest關(guān)聯(lián),ServiceTest的 beanFullName 是demo-student.service.test
      名稱 類型 說(shuō)明
      match string|regexp|(string|regexp)[] 針對(duì)哪些 Class 啟用

      切面:同步方法

      ServiceTest#actionSync輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopactionsync,自動(dòng)生成代碼骨架:

      action: AopAction<ClassSome, 'action'> = (_args, next, _receiver) => {
        return next();
      };
      

      調(diào)整代碼,然后添加 log 邏輯

      actionSync: AopAction<ServiceTest, 'actionSync'> = (_args, next, _receiver) => {
        const timeBegin = Date.now();
        const res = next();
        const timeEnd = Date.now();
        console.log('actionSync: ', timeEnd - timeBegin);
        return res;
      };
      
      • actionSync: 提供與ServiceTest同名的方法actionSync

      切面:異步方法

      ServiceTest#actionAsync輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopaction,自動(dòng)生成代碼骨架:

      action: AopAction<ClassSome, 'action'> = async (_args, next, _receiver) => {
        return await next();
      };
      

      調(diào)整代碼,然后添加 log 邏輯

      actionAsync: AopAction<ServiceTest, 'actionAsync'> = async (_args, next, _receiver) => {
        const timeBegin = Date.now();
        const res = await next();
        const timeEnd = Date.now();
        console.log('actionAsync: ', timeEnd - timeBegin);
        return res;
      };
      
      • actionAsync: 提供與ServiceTest同名的方法actionAsync

      切面:getter

      ServiceTest#get name輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopgetter,自動(dòng)生成代碼骨架:

      protected __get_xxx__: AopActionGetter<ClassSome, 'xxx'> = function (next, _receiver) {
        const value = next();
        return value;
      };
      

      調(diào)整代碼,然后添加 log 邏輯

      protected __get_name__: AopActionGetter<ServiceTest, 'name'> = function (next, _receiver) {
        const timeBegin = Date.now();
        const value = next();
        const timeEnd = Date.now();
        console.log('get name: ', timeEnd - timeBegin);
        return value;
      };
      
      • __get_name__: 對(duì)應(yīng)ServiceTest的 getter 方法get name

      切面:setter

      ServiceTest#set name輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopsetter,自動(dòng)生成代碼骨架:

      protected __set_xxx__: AopActionSetter<ClassSome, 'xxx'> = function (value, next, _receiver) {
        return next(value);
      }
      

      調(diào)整代碼,然后添加 log 邏輯

      protected __set_name__: AopActionSetter<ServiceTest, 'name'> = function (value, next, _receiver) {
        const timeBegin = Date.now();
        const res = next(value);
        const timeEnd = Date.now();
        console.log('set name: ', timeEnd - timeBegin);
        return res;
      };
      
      • __set_name__: 對(duì)應(yīng)ServiceTest的 setter 方法set name

      切面:__init__

      ServiceTest#__init__輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopinit,自動(dòng)生成代碼骨架:

      protected __init__: AopActionInit<ClassSome> = (_args, next, _receiver) => {
        next();
      };
      

      調(diào)整代碼,然后添加 log 邏輯

      protected __init__: AopActionInit<ServiceTest> = (_args, next, _receiver) => {
        const timeBegin = Date.now();
        next();
        const timeEnd = Date.now();
        console.log('__init__: ', timeEnd - timeBegin);
      };
      
      • __init__: 提供與ServiceTest同名的方法__init__

      切面:__dispose__

      ServiceTest#__dispose__輸出運(yùn)行時(shí)長(zhǎng)

      在 VSCode 編輯器中,輸入代碼片段aopdispose,自動(dòng)生成代碼骨架:

      protected __dispose__: AopActionDispose<ClassSome> = async (_args, next, _receiver) => {
        await next();
      };
      

      調(diào)整代碼,然后添加 log 邏輯

      protected __dispose__: AopActionDispose<ServiceTest> = async (_args, next, _receiver) => {
        const timeBegin = Date.now();
        await next();
        const timeEnd = Date.now();
        console.log('__dispose__: ', timeEnd - timeBegin);
      };
      
      • __dispose__: 提供與ServiceTest同名的方法__dispose__

      切面:__get__

      ServiceTest擴(kuò)展魔術(shù)方法

      在 VSCode 編輯器中,輸入代碼片段aopget,自動(dòng)生成代碼骨架:

      protected __get__: AopActionGet<ClassSome> = (_prop, next, _receiver) => {
        const value = next();
        return value;
      };
      

      調(diào)整代碼,然后添加自定義字段red

      protected __get__: AopActionGet<ServiceTest> = (prop, next, _receiver) => {
        if (prop === 'red') return '#FF0000';
        const value = next();
        return value;
      };
      
      • __get__: 約定的魔術(shù)方法名稱

      通過(guò)接口類型合并的機(jī)制為顏色提供類型定義

      declare module 'vona-module-demo-student' {
        export interface ServiceTest {
          red: string;
        }
      }
      

      切面:__set__

      ServiceTest擴(kuò)展魔術(shù)方法

      在 VSCode 編輯器中,輸入代碼片段aopset,自動(dòng)生成代碼骨架:

      protected __set__: AopActionSet<ClassSome> = (_prop, value, next, _receiver) => {
        return next(value);
      };
      

      調(diào)整代碼,為自定義字段red設(shè)置值

      private _colorRed: string | undefined;
      
      protected __set__: AopActionSet<ServiceTest> = (prop, value, next, _receiver) => {
        if (prop === 'red') {
          this._colorRed = value;
          return true;
        }
        return next(value);
      };
      
      • __set__: 約定的魔術(shù)方法名稱
      • 如果為prop設(shè)置了值,返回true,否則調(diào)用next方法

      然后調(diào)整__get__的邏輯:

      protected __get__: AopActionGet<ServiceTest> = (prop, next, _receiver) => {
      - if (prop === 'red') return '#FF0000';
      + if (prop === 'red') return this._colorRed;
        const value = next();
        return value;
      }
      

      切面:__method__

      ServiceTest的任何方法擴(kuò)展邏輯

      在 VSCode 編輯器中,輸入代碼片段aopmethod,自動(dòng)生成代碼骨架:

      protected __method__: AopActionMethod<ClassSome> = (_method, _args, next, _receiver) => {
        return next();
      };
      

      調(diào)整代碼,然后為方法actionSyncactionAsync添加 log 邏輯

      protected __method__: AopActionMethod<ServiceTest> = (method, _args, next, _receiver) => {
        if (method !== 'actionSync' && method !== 'actionAsync') {
          return next();
        }
        const timeBegin = Date.now();
        function done(res) {
          const timeEnd = Date.now();
          console.log(`method ${method}: `, timeEnd - timeBegin);
          return res;
        }
        const res = next();
        if (res?.then) {
          return res.then((res: any) => {
            return done(res);
          });
        }
        return done(res);
      };
      
      • __method__: 約定的魔術(shù)方法名稱
      • res?.then: 判斷返回值是否是 Promise 對(duì)象,進(jìn)行不同處理,從而兼容同步方法異步方法

      AOP順序

      針對(duì)同一個(gè)目標(biāo) Class,可以關(guān)聯(lián)多個(gè) AOP。所以,VonaJS 提供了兩個(gè)參數(shù),用于控制 AOP 的執(zhí)行順序

      1. dependencies

      比如,還有一個(gè) AOP demo-student:log3,我們希望執(zhí)行順序如下:demo-student:log3 > Current

      @Aop({
        match: 'demo-student.service.test',
      + dependencies: 'demo-student:log3',
      })
      class AopLog {}
      

      2. dependents

      dependents的順序剛好與dependencies相反,我們希望執(zhí)行順序如下:Current > demo-student:log3

      @Aop({
        match: 'demo-student.service.test',
      + dependents: 'demo-student:log3',
      })
      class AopLog {}
      

      AOP啟用/禁用

      可以控制 AOP 的啟用/禁用

      1. Enable

      src/backend/config/config/config.ts

      // onions
      config.onions = {
        aop: {
          'demo-student:log': {
      +     enable: false,
          },
        },
      };
      

      2. Meta

      可以讓 AOP 在指定的運(yùn)行環(huán)境生效

      名稱 類型 說(shuō)明
      flavor string|string[] 參見(jiàn): 運(yùn)行環(huán)境與Flavor
      mode string|string[] 參見(jiàn): 運(yùn)行環(huán)境與Flavor
      • 舉例
      @Aop({
      + meta: {
      +   flavor: 'normal',
      +   mode: 'dev',
      + },
      })
      class AopLog {}
      

      查看當(dāng)前生效的AOP清單

      可以直接在目標(biāo) Class action 中輸出當(dāng)前生效的 AOP 清單

      class ServiceTest {
        protected async __dispose__() {
      +   this.bean.onion.aop.inspect();
          this._name = '';
        }
      
      • this.bean.onion: 取得全局 Service 實(shí)例 onion
      • .aop: 取得與 AOP 相關(guān)的 Service 實(shí)例
      • .inspect: 輸出當(dāng)前生效的 AOP 清單

      當(dāng)方法被執(zhí)行時(shí),會(huì)自動(dòng)在控制臺(tái)輸出當(dāng)前生效的 AOP 清單,效果如下:

      aop-1

      資源

      posted @ 2025-10-27 09:51  濮水大叔  閱讀(84)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 精精国产XXX在线观看| 无码人妻一区二区三区精品视频| 奇米四色7777中文字幕| 国产精品福利自产拍在线观看| 中国女人高潮hd| 午夜福利国产区在线观看| 久久精品国产清自在天天线| 免费午夜无码片在线观看影院| 男人的天堂av社区在线| 欧美一区二区三区欧美日韩亚洲| 成人无码潮喷在线观看| 久久久精品波多野结衣av| 亚洲精品美女一区二区| 成人国产av精品免费网| 18禁在线一区二区三区| 依依成人精品视频在线观看| 日本一区二区a√成人片| 在线涩涩免费观看国产精品| 伊人久久精品无码二区麻豆| 99re6这里有精品热视频| 国产综合精品一区二区三区| 国产a网站| 大尺度国产一区二区视频| 国产中文三级全黄| 亚洲免费的福利片| 国产精品无码a∨麻豆| 99久久婷婷国产综合精品青草漫画| 国产午夜亚洲精品不卡网站| 余庆县| 99人中文字幕亚洲区三| 狠狠做五月深爱婷婷天天综合| 久久精品国产99久久久古代| 91精品亚洲一区二区三区| 国产精品成人久久电影| 亚洲综合精品一区二区三区| 日韩一区二区三区高清视频| 美女禁区a级全片免费观看| 亚洲伊人成无码综合网| 欧美精品18videosex性欧美| 国产福利社区一区二区| 18成人片黄网站www|