如何自定義中間件,實現業務代碼無侵入監控及攔截


 

 定義


  先看看某度某科怎么定義的 在軟件業,AOP為Aspect Oriented Programming的縮寫,意為:面向切面編程,通過預編譯方式和運行期間動態代理實現程序功能的統一維護的一種技術。AOP是OOP的延續,是軟件開發中的一個熱點,也是Spring框架中的一個重要內容,是函數式編程的一種衍生范型。利用AOP可以對業務邏輯的各個部分進行隔離,從而使得業務邏輯各部分之間的耦合度降低,提高程序的可重用性,同時提高了開發的效率。

 

  通俗的說就是, 在進入你的業務邏輯代碼之前,先執行一些方法操作,或者業務方法執行之后,繼續執行一些操作方法,可以用來做什么呢 
 

  • 你想給你的網站加上鑒權,
  • 對某些url,你認為不需要鑒權就可以訪問,
  • 對於某些url,你認為需要有特定權限的用戶才能訪問
  • 對於某些業務方法,我想監控調用頻率,執行性能
  • 還有騷操作的一種。收集用戶經常訪問的模塊,搜索關鍵字,喜歡看什么,使用習慣,(看到這里,笑容漸漸邪惡啊)提供模型給我們的算法和機器學習,用來優化我們的推薦機制,沒錯,就是你在一個網頁里搜索了東西,其他的app或者網頁,會推送相關的廣告給你(誒,有意思了啊)  

      

 

 總結


 

 個人理解其實AOP像OOP一樣,只是一種編程范式,AOP並沒有規定說,實現AOP協議的代碼,要用什么方式去實現,只要達到對業務代碼無侵入,就可以說是AOP
 
 
 
Demo

 

  閑言少敘,代碼見,先安裝nuget包
  Castle.Core 、 Autofac 、 Autofac.Extras.DynamicProxy
 
  這里先默認各位同學都會用autofac,不會也沒關系, 這個是完整的代碼鏈接 
  
  先定義最核心的中間件ServiceAOP類,繼承 IInterceptor 接口  , 有兩種方式實現aop攔截
      
  public class ServiceAOP: IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            DoSomething();
             Console.WriteLine("我要收集請求參數,發給我們算法模型同學 \"{0}\"  參數是 {1}... ", invocation.Method.Name,   string.Join(", ", invocation.Arguments.Select(a => (a ?? "").ToString()).ToArray()));
            //執行真實業務方法
            invocation.Proceed();
        }

        public void DoSomething()
        {
            Console.WriteLine("AOP,我先說話,你們service稍后再發言!");
        }
    }

 

 

第一種

  注冊自定義的aop攔截中間件

 builder.RegisterType<ServiceAOP>().As<IInterceptor>().InstancePerDependency();
  注冊業務接口方法的同時 注入aop攔截中間件
 //第一種方式
builder.RegisterType<TestServiceTwo>().As<ITestServiceTwo>().InterceptedBy(typeof(IInterceptor)) .InstancePerDependency().EnableClassInterceptors();

 

 

第二種

 
  還是先注冊自定義的aop攔截中間件
  
builder.Register(c => new ServiceAOP())

 

  再在需要攔截的程序集上注入aop攔截中間件,
var serviceAsm = Assembly.Load(new AssemblyName("Sharper.Core"));
            builder.RegisterAssemblyTypes(serviceAsm)
                       .Where(t => typeof(ITagService).IsAssignableFrom(t) && !t.GetTypeInfo().IsAbstract)
                       .AsImplementedInterfaces()
                       .InstancePerLifetimeScope()
                       .EnableInterfaceInterceptors(); //注入攔截器

 

  注冊程序集下所有繼承ITagService的接口,並注入攔截中間件

  最后在需要攔截的實現類上,直接通過打標簽的形式,即可實現攔截效果

[Intercept(typeof(ServiceAOP))]
    public class TestServiceOne : ITestServiceTwo
    {
        public async Task FirstMethod()
        {
            //doSomething 業務邏輯
            await Task.Run(() =>
            {
                Console.WriteLine($"業務方法:TestServiceTwo.FirstMethod()執行成功...");
            });
        }
    }

 

 

  這樣,在執行ITestServiceTwo 接口的業務方法之前,都會先執行aop中間件的方法操作

 


 
  有些同學想問,你這是業務接口方法,我們想攔擊ApiController控制器的請求,怎么處理呀,別急,這就來
 
  .net core web項目,可以對ApiController 控制器和業務方法 分別進行攔截,互不影響

  public class RequestCultureMiddleware
    {
        //定義私有只讀的委托 RequestDelegate
        private readonly RequestDelegate _next;

        public RequestCultureMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        //定義名為Invoke 或 InvokeAsync 的方法,參數為HttpContext 
        public async Task InvokeAsync(HttpContext context)
        {
            Console.WriteLine($"api 請求進來了,action{context.Request.Path}");
            // Call the next delegate/middleware in the pipeline
            await _next(context);
        }
    }
這個是微軟提供的,專門用於攔截http請求的中間件的組件,正好用於控制器攔截
在 Startup 的Configure 方法注入 使用中間件 app.UseMiddleware<RequestCultureMiddleware>();

 

這個就是本文好說的內容,其實aop中間件的玩法有很多,不止於上面說的哪幾種,好可以,實現緩存攔截,不同的業務方法 分別進行不同數據庫初始化,同學們可以探索一下新玩法,個人感覺,這個對項目的完整性和效率幫助還是挺大的。

 

 

 

歡迎各位轉載,轉載文章必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。

 

 
 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM