什么是面向切面編程AOP


一丶前言

  看過一些描述關於AOP切面編程的文章,寫的太概念化讓人很難理解,下面是我自己的理解,希望能幫到新人,如有錯誤歡迎指正。

二丶AOP是什么,它的應用場景是什么?

  AOP也跟IOC,OOP這些思想一樣它只是一種編程思想。Autofac、Spring.Net、Castle這些組件實現了AOP切面編程思想的框架。AOP說白了就是在運行時,動態的將代碼切入到類的指定方法的指定位置上,這種思想就是面向切面的編程思想。

如果你發現你的方法中有很多重復的代碼就可以考慮用aop來精簡代碼了。比如說你想監控每個方法的耗時,按照傳統的方法是每個方法都加上監控代碼,如果用AOP思想去解決這個問題,就可以把監控代碼放到方法的外面去寫。

AOP思想的應用場景:

  AOP切面緩存

  權限認證

  錯誤處理

  調試

  日志記錄

  性能監控

  數據持久化

  AOP事務

三丶AOP切面執行流程

  AOP切面有點像攔截器,不過跟攔截器有點區別。

四丶代碼例子

  這個例子開發環境使用的是.Net Core 3.0,用的AOP框架是Autofac,通過Nuget安裝Autofac.Extras.DynamicProxy組件。

  功能是AOP切面緩存,把查詢結果緩存到Redis里,不用每次都查詢數據庫。

  使用步驟

  1.Startup中把BlogCacheAOP切面 切入到Titan.Blog.AppService.dll下所有接口實現里。

var servicesDllFile = Path.Combine(basePath, "Titan.Blog.AppService.dll");//獲取項目絕對路徑
            var assemblysServices = Assembly.LoadFile(servicesDllFile);
            builder.RegisterAssemblyTypes(assemblysServices)
                .AsImplementedInterfaces()
                .InstancePerLifetimeScope()
                .EnableInterfaceInterceptors()
                .InterceptedBy(typeof(BlogCacheAOP));//AOP切面緩存

 

  2.切面公共代碼

  3.給方法標記特性,只有指定特性的方法才會執行公共代碼

        /// <summary>
        /// 獲取系統中所有的權限
        /// </summary>
        /// <returns></returns>
        [Caching(AbsoluteExpiration = 10)]
        public async Task<List<SysRoleModuleButtonDto>> GeRoleModule()
        {
            var dto = await _iSysRoleModuleButtonRepository.QueryAsNoTracking(x => x.ModuleType == 0);//
            var roleModuleButton = dto.MapToList<SysRoleModuleButton, SysRoleModuleButtonDto>();
            if (roleModuleButton.Count > 0)
            {
                foreach (var item in roleModuleButton)
                {
                    item.SysRole = _iSysRoleRepository.QueryBySql($"select * from SysRole where SysRoleId='{item.SysRoleId}' and IsDelete!=1 and RoleStatus=1").Result.FirstOrDefault();
                    item.SysModule = _iSysModuleRepository.QueryBySql($"select * from SysModule where SysModuleId='{item.SysModuleId}' and ModuleStatus=1 and IsDelete!=1").Result.FirstOrDefault();
                }

            }
            return roleModuleButton;
        }

這個是AOP切面緩存,它的功能是將包含CachingAttribute特性的方法的返回值緩存到Redis里,下次在訪問這個方法,會先去緩存中查詢如果有則直接跳過這個方法,直接從Redis里獲取之前緩存的結果集,如果沒有則會執行方法獲取返回值在緩存到Redis里。

以此,我們可以開發其他類似功能,比如性能監控,日志監控,AOP事務,是不是很強大。具體代碼執行流程請下載這個項目(下面有github地址),自己調試下上面的例子就明白了。

 

*****還有一個要注意的,我這個項目控制器和服務實現解耦了,如果沒有解耦的話,控制器直接調服務的話,AOP注冊方式和服務要做修改。

  1.Startup中AOP注冊代碼

 

            ////標記了虛方法virtual的才會進入切面
            var assemblysModels = Assembly.Load("Titan.Blog.AppService");
            builder.RegisterAssemblyTypes(assemblysModels)
                .EnableClassInterceptors()
                .InterceptedBy(typeof(BlogCacheAOP));

 

  2.方法要加上virtual,否則進不了切面

 

 

        /// <summary>
        /// 獲取系統中所有的權限
        /// </summary>
        /// <returns></returns>
        [Caching(AbsoluteExpiration = 10)]
        public virtual async Task<List<SysRoleModuleButtonDto>> GeRoleModule()
        {
            var dto = await _iSysRoleModuleButtonRepository.QueryAsNoTracking(x => x.ModuleType == 0);//
            var roleModuleButton = dto.MapToList<SysRoleModuleButton, SysRoleModuleButtonDto>();
            if (roleModuleButton.Count > 0)
            {
                foreach (var item in roleModuleButton)
                {
                    item.SysRole = _iSysRoleRepository.QueryBySql($"select * from SysRole where SysRoleId='{item.SysRoleId}' and IsDelete!=1 and RoleStatus=1").Result.FirstOrDefault();
                    item.SysModule = _iSysModuleRepository.QueryBySql($"select * from SysModule where SysModuleId='{item.SysModuleId}' and ModuleStatus=1 and IsDelete!=1").Result.FirstOrDefault();
                }

            }
            return roleModuleButton;
        }

 

  3.切面代碼不需要改動

 

四丶結語

  AOP思想實際上就是想把業務和公共的處理分開,對原有的代碼沒有一點入侵。我覺得學習一個新技術之前,先別讀那么多概念性的東西,感覺越看越糊塗,只會對學習新技術產生恐懼和抵觸心理。我們可以先看看新技術它能解決什么問題,實際應用場景是什么,這對學習新技術應該是有好處的。

 

五丶Github Demo,演示地址

 

Demo 源碼地址,順便給個Star謝謝了。 

 

演示地址:http://gaobili.cn:8600/swagger/index.html

 

 加群一起學習共同進步。群號:963718093

.Net Core 開源學習交流


免責聲明!

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



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