欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

什么是面向切面编程AOP

程序员文章站 2024-01-11 18:47:22
一丶前言 看过一些描述关于AOP切面编程的文章,写的太概念化让人很难理解,下面是我自己的理解,希望能帮到新人,如有错误欢迎指正。 二丶AOP是什么,它的应用场景是什么? AOP也跟IOC,OOP这些思想一样它只是一种编程思想。Autofac、Spring.Net、Castle这些组件实现了AOP切面 ......

一丶前言

  看过一些描述关于aop切面编程的文章,写的太概念化让人很难理解,下面是我自己的理解,希望能帮到新人,如有错误欢迎指正。

二丶aop是什么,它的应用场景是什么?

  aop也跟ioc,oop这些思想一样它只是一种编程思想。autofac、spring.net、castle这些组件实现了aop切面编程思想的框架。aop说白了就是在运行时,动态的将代码切入到类的指定方法的指定位置上,这种思想就是面向切面的编程思想。

如果你发现你的方法中有很多重复的代码就可以考虑用aop来精简代码了。比如说你想监控每个方法的耗时,按照传统的方法是每个方法都加上监控代码,如果用aop思想去解决问题,就可以把跟监控代码放到方法的外面去写。

aop思想的应用场景:

  aop切面缓存

  权限认证

  错误处理

  调试

  日志记录

  性能监控

  数据持久化

  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.切面公共代码

什么是面向切面编程AOP

  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谢谢了。