←←←←←←←←←←←← 快!點關注git
看過一些描述關於AOP切面編程的文章,寫的太概念化讓人很難理解,下面是我本身的理解,但願能幫到新人,若有錯誤歡迎指正。github
AOP也跟IOC,OOP這些思想同樣它只是一種編程思想。Autofac、Spring.Net、Castle這些組件實現了AOP切面編程思想的框架。AOP說白了就是在運行時,動態的將代碼切入到類的指定方法的指定位置上,這種思想就是面向切面的編程思想。sql
若是你發現你的方法中有不少重複的代碼就能夠考慮用aop來精簡代碼了。好比說你想監控每一個方法的耗時,按照傳統的方法是每一個方法都加上監控代碼,若是用AOP思想去解決問題,就能夠把跟監控代碼放到方法的外面去寫。編程
AOP思想的應用場景:緩存
AOP切面有點像攔截器,不過跟攔截器有點區別。架構
這個例子開發環境使用的是.Net Core 3.0,用的AOP框架是Autofac,經過Nuget安裝Autofac.Extras.DynamicProxy組件。併發
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.切面公共代碼async
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思想實際上就是想把業務和公共的處理分開,對原有的代碼沒有一點入侵。我以爲學習一個新技術以前,先別讀那麼多概念性的東西,感受越看越糊塗,只會對學習新技術產生恐懼和抵觸心理。咱們能夠先看看新技術它能解決什麼問題,應用場景是什麼,這對學習新技術應該是有好處的。
分享免費學習資料
針對於還會準備免費的Java架構學習資料(裏面有高可用、高併發、高性能及分佈式、Jvm性能調優、MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多個知識點的架構資料)
爲何某些人會一直比你優秀,是由於他自己就很優秀還一直在持續努力變得更優秀,而你是否是還在知足於現狀心裏在竊喜!但願讀到這的您能點個小贊和關注下我,之後還會更新技術乾貨,謝謝您的支持!
資料領取方式:加入Java技術交流羣963944895
,私信管理員便可免費領取