Spring_NET学习笔记——AOP的通知类型(基础篇) Level 300===

Spring_NET学习笔记——AOP的通知类型(基础篇) Level 300===
Spring_NET学习笔记——AOP的通知类型(基础篇) Level 300===

https://www.360docs.net/doc/828602237.html,学习笔记——AOP的通知类型(基础篇) Level 300 上篇我们学习了AOP的基本概念,我们回顾一下上篇提到的Advice(通知):所谓通知是指拦截到joinpoint(连接点)之后所要做的事情就是通知.通知分为前置通知,后置通知,异常通知,环绕通知。

https://www.360docs.net/doc/828602237.html,的通知既可由某个类的所有对象共享,也可由该类型的单个实例独占。共享的通知称为基于类型(per-class)的通知,而独占的通知称为基于实例(per-instance)的通知。

基于类型的通知最为常用。很多常用功能很适合用基于类型的通知实现,比如说事务。它们不依赖于目标对象的状态,也不会向目标对象添加新状态,仅仅对方法及其参数进行操作。

基于实例的通知比较适合做引入(introductions)。此时通知可以向目标对象添加状态。在AOP代理中,可以同时使用基于类型和基于实例的通知。https://www.360docs.net/doc/828602237.html,和spring框架略有不同,只有四种通知类型,没有spring框架的最终通知(目前我还没有实现最终通知,如果有朋友实现的话,可以给我留言)。

一、拦截环绕通知(around advice):https://www.360docs.net/doc/828602237.html,中最基本的通知类型是拦截环绕通知(interception around advice),即方法拦截器。拦截环绕通知继承IMethodInterceptor接口。注意其中IMethodInvocation.Proceed()方法的调用。该方法会依次调用拦截器链上的其它拦截器。大部分拦截器都需要调用这个方法并返回它的返回值。当然,也可以不调用Proceed方法,而返回一个其它值或抛出一个异常,但一般不太会这么做。

二、前置通知(before advise):是在IMethodInterceptor.Proceed()方法调用前的通知。继承自IMethodBeforeAdvice接口。

三、异常通知(throws advise):是在IMethodInterceptor.Proceed()方法调用时发生异常的通知。继承自IthrowsAdvice接口。IthrowsAdvice接口没有定义任何方法:它是一个标识接口(按:之所以用标识接口,原因有二:1、在通知方法中,只有最后一个参数是必须的。如果声明为接口的方法,参数列表就被固定了。2、如果第一个原因可以用重载的接口方法解决,那么这个原因就是使用标识接口的充分原因了:实现此接口的类必须声明一或多个通知方法,接口方法做不到这一点),用以表明实现它的类声明了一或多个强类型的异常通知方法。

四、后置通知(after returning advise):是在IMethodInterceptor.Proceed()方法调用后的通知。继承自IAfterReturningAdvice 接口。后置通知对切入点的执行没有影响,如果通知抛出异常,就会沿拦截器链向上抛出,从而中断拦截器链的继续执行。

代码实现:

准备条件

四种通知:

///

///环绕通知

///

public class AroundAdvise : IMethodInterceptor

{

public object Invoke(IMethodInvocation invocation)

{

Console.Out.WriteLine(string.Format(" 环绕通知:调用的方法 '{0}'", https://www.360docs.net/doc/828602237.html,));

Console.WriteLine();

object returnValue = null;

try

{

returnValue = invocation.Proceed();

}

catch

{

Console.Out.WriteLine(" 环绕通知:发生异常");

Console.WriteLine();

}

Console.Out.WriteLine(String.Format(" 环绕通知:返回值 '{0}'", returnValue));

return returnValue;

}

}

///

///前置通知

///

public class BeforeAdvise : IMethodBeforeAdvice

{

public void Before(MethodInfo method, object[] args, object target)

{

Console.Out.WriteLine(" 前置通知:调用的方法名 : " + https://www.360docs.net/doc/828602237.html,);

Console.Out.WriteLine(" 前置通知:目标 : " + target);

Console.Out.WriteLine(" 前置通知:参数为 : ");

if (args != null)

{

foreach (object arg in args)

{

Console.Out.WriteLine("\t: " + arg);

}

}

Console.WriteLine();

}

}

///

///异常通知

///

public class ThrowsAdvise : IThrowsAdvice

{

public void AfterThrowing(Exception ex)

{

string errorMsg = string.Format(" 异常通知:方法抛出的异常 : {0}", ex.Message);

Console.Error.WriteLine(errorMsg);

Console.WriteLine();

}

}

///

///后置通知

///

public class AfterReturningAdvise : IAfterReturningAdvice

{

public void AfterReturning(object returnValue, MethodInfo method, object[] args, object target)

{

Console.Out.WriteLine(" 后置通知:方法调用成功,方法名 : " + https://www.360docs.net/doc/828602237.html,);

Console.Out.WriteLine(" 后置通知:目标为 : " + target);

Console.Out.WriteLine(" 后置通知:参数 : ");

if (args != null)

{

foreach (object arg in args)

{

Console.Out.WriteLine("\t: " + arg);

}

}

Console.Out.WriteLine(" 后置通知:返回值是 : " + returnValue);

Console.WriteLine();

}

}

public interface IOrderService

{

object Save(object id);

}

一、没有异常的情况

public class OrderService : IOrderService

{

///

///拦截该方法

///

///

///

public object Save(object id)

{

//throw new Exception("由于XXX原因保存出错");

return"保存:" + id.ToString();

}

}

class Program

{

static void Main(string[] args)

{

ProxyFactory factory = new ProxyFactory(new OrderService());

factory.AddAdvice(new AroundAdvise());

factory.AddAdvice(new BeforeAdvise());

factory.AddAdvice(new AfterReturningAdvise());

factory.AddAdvice(new ThrowsAdvise());

IOrderService service = (IOrderService)factory.GetProxy();

object result = service.Save(1);

Console.WriteLine();

Console.WriteLine(string.Format("客户端返回值:{0}", result));

Console.ReadLine();

}

}

输出效果:见图1

图1

二、有异常的情况:

public class OrderService : IOrderService

{

///

///拦截该方法

///

///

///

public object Save(object id)

{

throw new Exception("由于XXX原因保存出错");

//return "保存:" + id.ToString();

}

}

输出效果:见图2

图2

从图与代码中,我们不难看出Advice(通知)的生命周期。拦截环绕通知(around advice)围绕着整个拦截过程;前置通知(before advise)在方法调用前执行;异常通知(throws advise)在调用方法时发生异常才执行,否则不执行;后置通知(after returning advise)在方法调用后执行,当调用时出现异常,则不执行后置通知(after returning advise)。

代码下载

参考自https://www.360docs.net/doc/828602237.html,中文手册

清华大学开题报告ppt

清华大学开题报告ppt 篇一:毕业论文开题报告 武汉工程大学计算机科学与工程学院 毕业论文开题报告 第 1 页共 4 页 (5)可以随时修改系统口令。 (6)灵活的数据备份、还原功能。 (7)系统最大限度地实现易安装性、易维护性和易操作性。 (8)系统运行稳定,安全可靠。 通过使用超市管理系统可以迅速提升超市的管理水平,降低经营成本,为提高效益和增强超市扩张能力,提供了有效的技术保障。本系统就是在这样的背景下提出的。另外在技术方面采用了较为先进的Java Swing技术和SQL Server XX,用来实现超市管理信息系统,包括系统登陆、基本资料、进货管理、销售管理、库存管理、系统维护、信息查询7个模块。 要求能够自觉运用数据库系统课程学习的理论知识指导软件设计;掌握信息管理系统的开发方法和步骤。整个应用系统的设计严格按照数据库设计的方法来进行,包括数据库的设计和应用程序的设计,两部分相辅相成。 数据库设计过程包含以下步骤:

需求分析:系统的目的、用户的各种需求、业务流程图、数据流程图; 概念结构设计:用E-R图来描述实体及实体间的联系; 逻辑结构设计:确定关系模式,各种约束的声明,如主码外码约束、唯一性约束、非空约束等。同时给出系统的功能模块组成图,系统各模块功能; 物理结构设计; 数据库实施; 数据库的实施阶段:数据库用SQL Server XX等创建,前端开发使用Java、.NET等实现。 通过此次课程设计提高自己独立分析问题、解决问题的能力。掌握从需求分析、数据库设计(概念设计、逻辑设计、物理设计)、编写程序、测试分析,撰写文档到最终答辩的整个过程。 参考文献: [1] 刘京华等. JAVA WEB整合开发王者归来[M].北京:清华大学出版社,XX [2] 王俊杰. 精通JAVA SCRIPT动态网页编程[M].北京:人民邮电出版社,XX [3] 李宁. Java Web编程实战宝典[M].北京:清华大学出版社,XX [4] 孙更新. Java程序开发大全[M].北京:中国铁道出

JavaScript设计模式

JavaScript设计模式的作用——提高代码的重用性,可读性,使代码更容易的维护和扩展。 1.单体模式,工厂模式,桥梁模式个人认为这个一个优秀前端必须掌握的模式,对抽象编程和接口编程都非常有好处。 2.装饰者模式和组合模式有很多相似的地方,它们都与所包装的对象实现同样的接口并且会把任何方法的调用传递给这些对象。装饰者模式和组合模式是本人描述的较吃力的两个模式,我个人其实也没用过,所以查了很多相关资料和文档,请大家海涵。 3.门面模式是个非常有意思的模式,几乎所有的JavaScript库都会用到这个模式,假如你有逆向思维或者逆向编程的经验,你会更容易理解这个模式(听起来有挑战,其实一接触你就知道这是个很简单的模式);还有配置器模式得和门面模式一块拿来说,这个模式对现有接口进行包装,合理运用可以很多程度上提高开发效率。这两个模式有相似的地方,所以一块理解的话相信都会很快上手的。 4.享元模式是一种以优化为目的的模式。 5.代理模式主要用于控制对象的访问,包括推迟对其创建需要耗用大量计算资源的类得实例化。 6.观察者模式用于对对象的状态进行观察,并且当它发生变化时能得到通知的方法。用于让对象对事件进行监听以便对其作出响应。观察者模式也被称为“订阅者模式”。 7.命令模式是对方法调用进行封装的方式,用命名模式可以对方法调用进行参数化和传递,然后在需要的时候再加以执行。 8.职责链模式用来消除请求的发送者和接收者之间的耦合。 JavaScript设计模式都有哪些? 单体(Singleton)模式:绝对是JavaScript中最基本最有用的模式。 单体在JavaScript的有多种用途,它用来划分命名空间。可以减少网页中全局变量的数量(在网页中使用全局变量有风险);可以在多人开发时避免代码的冲突(使用合理的命名空间)等等。 在中小型项目或者功能中,单体可以用作命名空间把自己的代码组织在一个全局变量名下;在稍大或者复杂的功能中,单体可以用来把相关代码组织在一起以便日后好维护。

十 大 经 典 排 序 算 法 总 结 超 详 细

前端资源收集 前端资-源收集 收集的资-源 44个 Javascript 变态题解析 javascript 变态题解析 正则表达式收集 正则表达式收集 十大经典排序算法总结(JavaScript描述)排序算法的总结 前端工具库汇总 前端工具库总结 怎么学JavaScript? 学习javascript 的学习指导 不定期更新 JavaScript技巧 javascript 编码技巧总结 H5项目常见问题汇总及解决方案 高质量的常见问题汇总 廖雪峰的 git 教-程 Git忽略规则.gitignore梳理 git 配置提交规则 全局环境,执行环境

setTimeout promises 很酷,但很多人并没有理解就在用了 promises 使用错误汇总 promises webpack 2 中文文档 输入url后的加载过程 详细解答从输入URL 到页面显示的过程 数组Array.prototype方法 介绍了数组的一些新的方法 移动端真机调试 Web 客户端存储 ESLint中文指南 webpack 2 集成ESLint react-webpack2-skeleton webpack 2 react 成功案例,包括热加载 cookie 小结 CSS定制多行省略 Ajax 知识体系大梳理 js+nodejs完成文件上传 用 webpack 实现持久化缓存 搜罗一切webpack的好文章好工具 深入理解 CSS:字体度量、line-height 和 vertical-align

原生JS中DOM节点相关API合集 正则表达式前端使用手册 聊一聊H5应用缓存-Manifest fetch进阶指南 mozilla 开发者网络 深入理解javascript原型和闭包系列JavaScript深入系列 深度长文 JavaScript数组所有API全解密你真的懂 JavaScript 的正则吗?webpack2 终极优化 文件上传那些事儿 写给前端工程师的DNS基础知识 初识weex(前端视角) - 环境搭建 前端命名规范 正则表达式 总有你要的编程书单(GitHub )JavaScript深入系列 javascript 的一些功能点 如何在小程序中调用本地接口 移动端浏览器调试方法汇总 HTML5移动开发中的input输入框类型 互联网协议入门

javascript设计模式介绍(二) 构造函数模式

本文由我司收集整编,推荐下载,如有疑问,请与我司联系 javascript 设计模式介绍(二)构造函数模式 2016/04/22 0 我们可以通过创建自定义的构造函数,从而定义自定义对象类型 的属性和方法。 例如: function Person(name.age,sex){https://www.360docs.net/doc/828602237.html, = name;this.age = age;this.sex = sex;this.sayName = function(){ alert(https://www.360docs.net/doc/828602237.html,); }}然后我们实例一个Personvar person1 = new Person(john ,18, 男var person1 = new Person(Rose ,17, 女 我们注意到,Person()中的代码: 没有显式地创建对象; 直接将属性和方法赋给了this 对象; 没有return 语句。 此外,还应该注意到函数名Person 使用的是大写字母P。按照惯例,构造函数始 终都应该以一个大写字母开头,而非构造函数则应该以一个小写字母开头。这个做 法借鉴自其他OO 语言,主要是为了区别于ECMAScript 中的其他函数;因为构造 函数本身也是函数,只不过可以用来创建对象而已。 要创建Person 的新实例,必须使用new 操作符。以这种方式调用构造函数实际 上会经历以下4 个步骤:(1) 创建一个新对象;(2) 将构造函数的作用域赋给新对象 (因此this 就指向了这个新对象);(3) 执行构造函数中的代码(为这个新对象添加 属性);(4) 返回新对象。 person1 和person2 分别保存着Person 的一个不同的实例。这两个对象都有一个constructor(构造函数)属性,该属性指向Person,如下所示。 alert(person1.constructor == Person); //true alert(person2.constructor == Person); //true 对象的constructor 属性最初是用来标识对象类型的。但是,提到检测对象类型, 还是instanceof 操作符要更可靠一些。我们在这个例子中创建的所有对象既是Object 的实例,同时也是Person 的实例,这一点通过instanceof 操作符可以得到验 证。

javascript设计模式

【Javascript设计模式1】-单例模式 《parctical common lisp》的作者曾说,如果你需要一种模式,那一定是哪里出了问题。他所说的问题是指因为语言的天生缺陷,不得不去寻求和总结一种通用的解决方案。 不管是弱类型或强类型,静态或动态语言,命令式或说明式语言、每种语言都有天生的优缺点。一个牙买加运动员,在短跑甚至拳击方面有一些优势,在练瑜伽上就欠缺一些。 术士和暗影牧师很容易成为一个出色的辅助,而一个背着梅肯满地图飞的敌法就会略显尴尬。换到程序中, 静态语言里可能需要花很多功夫来实现装饰者,而js由于能随时往对象上面扔方法,以至于装饰者模式在js里成了鸡肋。 讲javascript设计模式的书还比较少. Pro javaScript Design Patterns.是比较经典的一本,但是它里面的例子举得比较啰嗦,所以结合我在工作中写过的代码,把我的理解总结一下。如果我的理解出现了偏差,请不吝指正。 一单例模式 单例模式的定义是产生一个类的唯一实例,但js本身是一种“无类”语言。很多讲js设计模式的文章把{}当成一个单例来使用也勉强说得通。因为js生成对象的方式有很多种,我们来看下另一种更有意义的单例。 有这样一个常见的需求,点击某个按钮的时候需要在页面弹出一个遮罩层。比如https://www.360docs.net/doc/828602237.html,点击登录的时候. 这个生成灰色背景遮罩层的代码是很好写的.

问题是, 这个遮罩层是全局唯一的, 那么每次调用createMask都会创建一个新的div, 虽然可以在隐藏遮罩层的把它remove掉. 但显然这样做不合理. 再看下第二种方案, 在页面的一开始就创建好这个div. 然后用一个变量引用它. 这样确实在页面只会创建一个遮罩层div, 但是另外一个问题随之而来, 也许我们永远都不需要这个遮罩层, 那又浪费掉一个div, 对dom节点的任何操作都应该非常吝啬. 如果可以借助一个变量. 来判断是否已经创建过div呢? 看起来不错, 到这里的确完成了一个产生单列对象的函数. 我们再仔细看这段代码有什么不妥.

Java程序员必备的15个框架,前3个地位无可动摇!

Java程序员必备的15个框架,前3个地位无可动摇! Java 程序员方向太多,且不说移动开发、大数据、区块链、人工智能这些,大部分Java 程序员都是Java Web/后端开发。那作为一名Java Web 开发程序员必须需要熟悉哪些框架呢? 今天,栈长我给大家列举了一些通用的、必须掌握的框架,学会这些,20K+ 不是问题。 1.Spring 毫无疑问,Spring 框架现在是Java 后端框架家族里面最强大的一个,其拥有IOC 和AOP 两大利器,大大简化了软件开发复杂性。并且,Spring 现在能与所有主流开发框架集成,可谓是一个万能框架,Spring 让JAVA 开发变得更多简单。 官网: https://spring.io/projects/spring-framework 源码: https://https://www.360docs.net/doc/828602237.html,/spring-projects/spring-framework 推荐: 2.Spring MVC

Spring MVC 是一个MVC 开源框架,用来代替Struts。它是Spring 项目里面的一个重要组成部分,能与Spring IOC 容器紧密结合,以及拥有松耦合、方便配置、代码分离等特点,让JAVA 程序员开发WEB 项目变得更加容易。 官网: https://spring.io/projects/spring-framework 源码: https://https://www.360docs.net/doc/828602237.html,/spring-projects/spring-framework 3.Spring Boot Spring Boot 是Spring 开源组织下的一个子项目,也是Spring 组件一站式解决方案,主要是为了简化使用Spring 框架的难度,简省繁重的配置。 Spring Boot提供了各种组件的启动器(starters),开发者只要能配置好对应组件参数,Spring Boot 就会自动配置,让开发者能快速搭建依赖于Spring 组件的Java 项目。官网: https://spring.io/projects/spring-boot 源码: https://https://www.360docs.net/doc/828602237.html,/spring-projects/spring-boot 推荐:

相关主题
相关文档
最新文档