经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » 设计模式 » 查看文章
面向切面编程AOP
来源:cnblogs  作者:冰乐  时间:2019/9/20 9:49:31  对本文有异议

最开始接触AOP这个概念,是在大学Java课程中(具体哪本忘记了,JavaWeb?)接触到的。当时的理解就是,一个请求过来,自上而下,突然从中间切一刀。从那个图是这样理解的,文字描述的都忘记了。关于AOP的博客有好多,在工作中需要用到,我也是看着博客,外加视频学习来理解的。

http://wayfarer.cnblogs.com/articles/241012.html

这篇博客,写的还是蛮详细的。下面只是我自己的总结。

AOP不是一种设计模式,而是一种编程思想,和POP,OOP一样,是OOP的扩展,AOP的出现并不能代替OOP。

POP,面向过程编程:

  符合逻辑思维,线性的处理问题,但是无法应对复杂的系统

OOP面向对象编程:

  万物皆对象,对象交互完成功能,功能叠加成模块,模块组成系统,才有机会搭建复杂的大型的软件系统。

  下面以一个例子来作为对比:

    砖块--------墙---------房间---------大厦

    类--------功能点------模块---------系统

  砖块应该是稳定的,说明是静态,不变的。在程序开发的过程中,类确实会变化的,增加日志/异常/权限/缓存/事务等,只能修改类。

  在GOF23种设计模式,应对变化的,核心套路是依赖抽象,细节就可以变化,但是只能替换整个对象,没办法把一个类动态改变。

 AOP面向切面编程:

  允许开发者动态的修改静态的OO模型,就像现实生活中对象在生命周期中会不断的改变自身。AOP是一种编程思想,是OOP思想的补充。

  正式因为能够动态的扩展功能,所以在程序设计的时候,就可以有以下好处:

    1、聚焦核心业务逻辑,权限/异常/缓存/事务,通过功能可以通过AOP方式添加,程序设计简单。

    2、动态扩展,集中管理,代码复用,规范化。

下面,用装饰器模式,去实现一个AOP功能:

  1. /// <summary>
  2. /// 装饰器模式实现静态代理
  3. /// AOP 在方法前后增加自定义的方法
  4. /// </summary>
  5. public class DecoratorAOP
  6. {
  7. public static void Show()
  8. {
  9. User user = new User()
  10. {
  11. Name = "bingle",
  12. Password = "123123123123"
  13. };
  14. IUserProcessor processor = new UserProcessor();
  15. processor.RegUser(user);
  16. Console.WriteLine("***************");
  17. processor = new UserProcessorDecorator(processor);
  18. processor.RegUser(user);
  19. }
  20. public interface IUserProcessor
  21. {
  22. void RegUser(User user);
  23. }
  24. public class UserProcessor : IUserProcessor
  25. {
  26. public void RegUser(User user)
  27. {
  28. Console.WriteLine("用户已注册。Name:{0},PassWord:{1}", user.Name, user.Password);
  29. }
  30. }
  31. /// <summary>
  32. /// 装饰器的模式去提供一个AOP功能
  33. /// </summary>
  34. public class UserProcessorDecorator : IUserProcessor
  35. {
  36. private IUserProcessor _UserProcessor { get; set; }
  37. public UserProcessorDecorator(IUserProcessor userprocessor)
  38. {
  39. this._UserProcessor = userprocessor;
  40. }
  41. public void RegUser(User user)
  42. {
  43. BeforeProceed(user);
  44. this._UserProcessor.RegUser(user);
  45. AfterProceed(user);
  46. }
  47. /// <summary>
  48. /// 业务逻辑之前
  49. /// </summary>
  50. /// <param name="user"></param>
  51. private void BeforeProceed(User user)
  52. {
  53. Console.WriteLine("方法执行前");
  54. }
  55. /// <summary>
  56. /// 业务逻辑之后
  57. /// </summary>
  58. /// <param name="user"></param>
  59. private void AfterProceed(User user)
  60. {
  61. Console.WriteLine("方法执行后");
  62. }
  63. }
  64. }
View Code

实现AOP的多种方式:

  1、静态实现----装饰器/代理模式

  2、动态实现----Remoting/Castlet

  3、静态植入---PostSharp(收费)----扩展编译工具,生成的加入额外代码

  4、依赖注入容器的AOP扩展(Unity)

  5、MVC的Filter---特性标机,然后该方法执行前后就多了逻辑

  之前看到有的人认为,在.NET Core中的中间件,也是AOP的一种实现。也有一些人认为不是。博主认为,.NET Core中的中间件并不是AOP的一种实现。等后续随笔记载到中间件的时候,再去详细说明吧。

  依赖注入容器的AOP扩展(扩展)

  基于配置文件的Unity。

  首先,用Nuget引入Unity想换的程序集

 

 下面是配置文件: 

  1. <configuration>
  2. <configSections>
  3. <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Unity.Configuration"/>
  4. <!--Microsoft.Practices.Unity.Configuration.UnityConfigurationSection-->
  5. </configSections>
  6. <unity>
  7. <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Unity.Interception.Configuration"/>
  8. <containers>
  9. <container name="aopContainer">
  10. <extension type="Interception"/>
  11. <register type="MyAOP.UnityWay.IUserProcessor,MyAOP" mapTo="MyAOP.UnityWay.UserProcessor,MyAOP">
  12. <interceptor type="InterfaceInterceptor"/>
  13. <interceptionBehavior type="MyAOP.UnityWay.MonitorBehavior, MyAOP"/>
  14.  
  15. <interceptionBehavior type="MyAOP.UnityWay.LogBeforeBehavior, MyAOP"/>
  16. <interceptionBehavior type="MyAOP.UnityWay.ParameterCheckBehavior, MyAOP"/>
  17. <interceptionBehavior type="MyAOP.UnityWay.CachingBehavior, MyAOP"/>
  18. <interceptionBehavior type="MyAOP.UnityWay.ExceptionLoggingBehavior, MyAOP"/>
  19. <interceptionBehavior type="MyAOP.UnityWay.LogAfterBehavior, MyAOP"/>
  20. </register>
  21. </container>
  22. </containers>
  23. </unity>
  24. </configuration>
View Code

 

 使用EntLib\PIAB Unity 实现动态代理:

  1. public class UnityConfigAOP
  2. {
  3. [Obsolete]
  4. public static void Show()
  5. {
  6. User user = new User()
  7. {
  8. Name = "bingle",
  9. Password = "1234567890123456789"
  10. };
  11. //配置UnityContainer
  12. IUnityContainer container = new UnityContainer();
  13. ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
  14. fileMap.ExeConfigFilename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "CfgFiles\\Unity.Config");
  15. Configuration configuration = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);
  16. UnityConfigurationSection configSection = (UnityConfigurationSection)configuration.GetSection(UnityConfigurationSection.SectionName);
  17. configSection.Configure(container, "aopContainer");
  18. IUserProcessor processor = container.Resolve<IUserProcessor>();
  19. processor.RegUser(user);
  20. processor.GetUser(user);
  21. }
  22. }
View Code
  1. public class LogAfterBehavior : IInterceptionBehavior
  2. {
  3. public IEnumerable<Type> GetRequiredInterfaces()
  4. {
  5. return Type.EmptyTypes;
  6. }
  7. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  8. {
  9. Console.WriteLine("LogAfterBehavior");
  10. foreach (var item in input.Inputs)
  11. {
  12. Console.WriteLine(item.ToString());//反射获取更多信息
  13. }
  14. IMethodReturn methodReturn = getNext()(input, getNext);
  15. Console.WriteLine("LogAfterBehavior" + methodReturn.ReturnValue);
  16. return methodReturn;
  17. }
  18. public bool WillExecute
  19. {
  20. get { return true; }
  21. }
  22. }
View Code
  1. /// <summary>
  2. /// 不需要特性
  3. /// </summary>
  4. public class LogBeforeBehavior : IInterceptionBehavior
  5. {
  6. public IEnumerable<Type> GetRequiredInterfaces()
  7. {
  8. return Type.EmptyTypes;
  9. }
  10. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  11. {
  12. Console.WriteLine("LogBeforeBehavior");
  13. foreach (var item in input.Inputs)
  14. {
  15. Console.WriteLine(item.ToString());//反射获取更多信息
  16. }
  17. return getNext().Invoke(input, getNext);
  18. }
  19. public bool WillExecute
  20. {
  21. get { return true; }
  22. }
  23. }
View Code
  1. public class ExceptionLoggingBehavior : IInterceptionBehavior
  2. {
  3. public IEnumerable<Type> GetRequiredInterfaces()
  4. {
  5. return Type.EmptyTypes;
  6. }
  7. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  8. {
  9. Console.WriteLine("ExceptionLoggingBehavior");
  10. IMethodReturn methodReturn = getNext()(input, getNext);
  11. if (methodReturn.Exception == null)
  12. {
  13. Console.WriteLine("无异常");
  14. }
  15. else
  16. {
  17. Console.WriteLine($"异常:{methodReturn.Exception.Message}");
  18. }
  19. return methodReturn;
  20. }
  21. public bool WillExecute
  22. {
  23. get { return true; }
  24. }
  25. }
View Code
  1. /// <summary>
  2. /// 不需要特性
  3. /// </summary>
  4. public class CachingBehavior : IInterceptionBehavior
  5. {
  6. public IEnumerable<Type> GetRequiredInterfaces()
  7. {
  8. return Type.EmptyTypes;
  9. }
  10. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  11. {
  12. Console.WriteLine("CachingBehavior");
  13. //input.Target.GetType().GetCustomAttributes()
  14. if (input.MethodBase.Name.Equals("GetUser"))
  15. return input.CreateMethodReturn(new User() { Id = 234, Name = "Eleven" });
  16. return getNext().Invoke(input, getNext);
  17. }
  18. public bool WillExecute
  19. {
  20. get { return true; }
  21. }
  22. }
View Code
  1. /// <summary>
  2. /// 性能监控的AOP扩展
  3. /// </summary>
  4. public class MonitorBehavior : IInterceptionBehavior
  5. {
  6. public IEnumerable<Type> GetRequiredInterfaces()
  7. {
  8. return Type.EmptyTypes;
  9. }
  10. public IMethodReturn Invoke(IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
  11. {
  12. Console.WriteLine(this.GetType().Name);
  13. string methodName = input.MethodBase.Name;
  14. Stopwatch stopwatch = new Stopwatch();
  15. stopwatch.Start();
  16. var methodReturn = getNext().Invoke(input, getNext);//后续逻辑执行
  17. stopwatch.Stop();
  18. Console.WriteLine($"{this.GetType().Name}统计方法{methodName}执行耗时{stopwatch.ElapsedMilliseconds}ms");
  19. return methodReturn;
  20. }
  21. public bool WillExecute
  22. {
  23. get { return true; }
  24. }
  25. }
View Code

 

原文链接:http://www.cnblogs.com/taotaozhuanyong/p/11552694.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号