面向切面编程(AOP)
一、引言:
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
二、静态拦截方式实现AOP
静态拦截方式最为简单,只是从原理上面描述AOP的实现过程。
public class Order
{
public int Id { set; get; }
public string Name { set; get; }
public int Count { set; get; }
public double Price { set; get; }
public string Desc { set; get; }
} public interface IOrderProcessor
{
void Submit(Order order);
}
public class OrderProcessor : IOrderProcessor
{
public void Submit(Order order)
{
Console.WriteLine("提交订单");
}
} public class OrderProcessorDecorator : IOrderProcessor
{
public IOrderProcessor OrderProcessor { get; set; }
public OrderProcessorDecorator(IOrderProcessor orderprocessor)
{
OrderProcessor = orderprocessor;
}
public void Submit(Order order)
{
PreProceed(order);
OrderProcessor.Submit(order);
PostProceed(order);
}
public void PreProceed(Order order)
{
Console.WriteLine("提交订单前,进行订单数据校验....");
if (order.Price < )
{
Console.WriteLine("订单总价有误,请重新核对订单。");
}
} public void PostProceed(Order order)
{
Console.WriteLine("提交带单后,进行订单日志记录......");
Console.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss") + "提交订单,订单名称:" + order.Name + ",订单价格:" + order.Price);
}
}
调用方式:
Order order = new Order() { Id = , Name = "lee", Count = , Price = 100.00, Desc = "订单测试" };
IOrderProcessor orderprocessor = new OrderProcessorDecorator(new OrderProcessor());
orderprocessor.Submit(order);
三、动态代理实现AOP
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;
using Microsoft.Practices.EnterpriseLibrary.PolicyInjection; namespace ConsoleDmeo.AOP
{
public class User
{
public string Name { set; get; }
public string PassWord { set; get; }
} #region 1、定义特性方便使用
public class LogHandlerAttribute : HandlerAttribute
{
public string LogInfo { set; get; }
public int Order { get; set; }
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogHandler() { Order = this.Order, LogInfo = this.LogInfo };
}
}
#endregion #region 2、注册对需要的Handler拦截请求
public class LogHandler : ICallHandler
{
public int Order { get; set; }
public string LogInfo { set; get; } //这个方法就是拦截的方法,可以规定在执行方法之前和之后的拦截
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
Console.WriteLine("LogInfo内容" + LogInfo);
//0.解析参数
var arrInputs = input.Inputs;
if (arrInputs.Count > )
{
var oUserTest1 = arrInputs[] as User;
}
//1.执行方法之前的拦截
Console.WriteLine("方法执行前拦截到了");
//2.执行方法
var messagereturn = getNext()(input, getNext); //3.执行方法之后的拦截
Console.WriteLine("方法执行后拦截到了");
return messagereturn;
}
}
#endregion #region 3、用户定义接口和实现
public interface IUserOperation
{
void Test(User oUser);
void Test2(User oUser, User oUser2);
} //这里必须要继承这个类MarshalByRefObject,否则报错
public class UserOperation : MarshalByRefObject, IUserOperation
{
private static UserOperation oUserOpertion = null;
public UserOperation()
{
//oUserOpertion = PolicyInjection.Create<UserOperation>();
} //定义单例模式将PolicyInjection.Create<UserOperation>()产生的这个对象传出去,这样就避免了在调用处写这些东西
public static UserOperation GetInstance()
{
if (oUserOpertion == null)
oUserOpertion = PolicyInjection.Create<UserOperation>(); return oUserOpertion;
}
//调用属性也会拦截
public string Name { set; get; } //[LogHandler],在方法上面加这个特性,只对此方法拦截
[LogHandler(LogInfo = "Test的日志为aaaaa")]
public void Test(User oUser)
{
Console.WriteLine("Test方法执行了");
} [LogHandler(LogInfo = "Test2的日志为bbbbb")]
public void Test2(User oUser, User oUser2)
{
Console.WriteLine("Test2方法执行了");
}
}
#endregion
}
调用方式:
var oUserTest1 = new ConsoleDmeo.AOP.User() { Name = "test2222", PassWord = "yxj" };
var oUserTest2 = new ConsoleDmeo.AOP.User() { Name = "test3333", PassWord = "yxj" };
var oUser = UserOperation.GetInstance();
oUser.Test(oUserTest1);
oUser.Test2(oUserTest1, oUserTest2);
四、MVC中的filter实现AOP
自定义授权类:
public class MyAuthorizeAttribute:AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
filterContext.Result = new RedirectResult("/Login/Index");
base.OnAuthorization(filterContext);
} protected override bool AuthorizeCore(HttpContextBase httpContext)
{
string userName = httpContext.User.Identity.Name; if (userName == "admin")
{
return true;
}
else
{
return false;
}
}
}
上面自定义了请求授权方法和自定义授权检查,在局部控制器中使用:
[MyAuthorize]
public ActionResult Index()
{
return View();
}
面向切面编程(AOP)的更多相关文章
- 设计模式之面向切面编程AOP
动态的将代码切入到指定的方法.指定位置上的编程思想就是面向切面的编程. 代码只有两种,一种是逻辑代码.另一种是非逻辑代码.逻辑代码就是实现功能的核心代码,非逻辑代码就是处理琐碎事务的代码,比如说获取连 ...
- Spring学习手札(二)面向切面编程AOP
AOP理解 Aspect Oriented Program面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术. 但是,这种说法有些片面,因为在软件工程中,AOP的价值体现的并 ...
- Spring学习笔记:面向切面编程AOP(Aspect Oriented Programming)
一.面向切面编程AOP 目标:让我们可以“专心做事”,避免繁杂重复的功能编码 原理:将复杂的需求分解出不同方面,将公共功能集中解决 *****所谓面向切面编程,是一种通过预编译方式和运行期动态代理实现 ...
- Spring框架学习笔记(2)——面向切面编程AOP
介绍 概念 面向切面编程AOP与面向对象编程OOP有所不同,AOP不是对OOP的替换,而是对OOP的一种补充,AOP增强了OOP. 假设我们有几个业务代码,都调用了某个方法,按照OOP的思想,我们就会 ...
- Spring之控制反转——IoC、面向切面编程——AOP
控制反转——IoC 提出IoC的目的 为了解决对象之间的耦合度过高的问题,提出了IoC理论,用来实现对象之间的解耦. 什么是IoC IoC是Inversion of Control的缩写,译为控制 ...
- 【串线篇】面向切面编程AOP
面向切面编程AOP 描述:将某段代码“动态”的切入到“指定方法”的“指定位置”进行运行的一种编程方式 (其底层就是Java的动态代理)spring对其做了简化书写 场景: 1).AOP加日志保存到数据 ...
- 04 Spring:01.Spring框架简介&&02.程序间耦合&&03.Spring的 IOC 和 DI&&08.面向切面编程 AOP&&10.Spring中事务控制
spring共四天 第一天:spring框架的概述以及spring中基于XML的IOC配置 第二天:spring中基于注解的IOC和ioc的案例 第三天:spring中的aop和基于XML以及注解的A ...
- [译]如何在ASP.NET Core中实现面向切面编程(AOP)
原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...
- Spring框架系列(4) - 深入浅出Spring核心之面向切面编程(AOP)
在Spring基础 - Spring简单例子引入Spring的核心中向你展示了AOP的基础含义,同时以此发散了一些AOP相关知识点; 本节将在此基础上进一步解读AOP的含义以及AOP的使用方式.@pd ...
- 面向切面编程AOP
本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...
随机推荐
- 第五周 day5 python学习笔记
1.软件开发的常规目录结构 更加详细信息参考博客:http://www.cnblogs.com/alex3714/articles/5765046.html 2.python中的模块 ...
- vscode:配置git
1.下载git,并找到安装git的文件位置,并找到git文件夹下面的Bin文件夹 2.配置环境变量 位置:右击‘计算机’->属性->高级系统设置->环境变量 最后点击确定即可 ...
- Python之条件判断和循环(入门4)
转载请标明出处: http://www.cnblogs.com/why168888/p/6407755.html 本文出自:[Edwin博客园] Python之条件判断和循环 1. Python之if ...
- vim使用常看
原网址http://www.runoob.com/linux/linux-vim.html 补充参考https://blog.csdn.net/w178191520/article/details/8 ...
- 分享Spring Scheduled定时器的用法
摘要:在coding中经常会用到定时器,指定每隔1个小时,或是每天凌晨2点执行一段代码段,若是使用java.util.Timer来做这种事情,未免重复造轮子.幸亏Spring中封装有定时器,而且非常好 ...
- Webpack笔记(三)——一款破产版脚手架的开发
前些天一直在学习入门Webpack,后来尝试了自己搭建一下一个简单的React开发环境,后来就在想可不可以自己写一个简单的脚手架,以免每次搭建一个简单的开发环境都需要自己一个个的配置,这样很麻烦,使用 ...
- Spring Framework5.0 学习(4)—— Bean的命名id和name区别
Spring中Bean的命名 1.每个Bean可以有一个id属性,并可以根据该id在IoC容器中查找该Bean,该id属性值必须在IoC容器中唯一: 2.可以不指定id属性,只指定全限定类名,如: & ...
- 22、整合mybatis
搭建环境: 1).创建工程需要的maven坐标 这个mybatis的starter是mybatis官方出的适应springboot 2).数据连接池的使用 引入Druid数据连接池 <depen ...
- PHP日志 LOG4PHP 的配置与使用
维护了 一个老项目, 没有日志功能, 就给加了这个log4php, 主要是集成进去很简单,使用起来也够用了. 1.下载log4php 2.创建配置文件 log4php_config.xml < ...
- 关于 Vue.js+Element-UI 日期控件 日期范围选择
理想效果 : 也就是说前面时间框的时间能选的范围应该小于等于后面的时间框; 后面时间框能选的范围应该大于等于前面的时间框; 示例代码 : 页面: <el-form-item label=&quo ...