简单的说,Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。

上文已经介绍模拟IoC实现,这篇文章来动手模拟AOP。

AOP简述

面向对象强调"一切皆是对象",是对真实世界的模拟。然而面向对象也并不是完美无缺的,它更注重于对象层次结构方面的东西。对于怎样更好的管理对象行为内部结构,还存在着些许不足。那么我们怎样使这个问题的得到更完美的解决呢?答案就是AOP。

AOP:Aspect-Oriented Programming。AOP是OOP的补充。是GOF的延续。

我们知道设计模式是对于面向对象设计中经验的总结。它孜孜不断追求的就是调用者与被调用者之间的解耦。

有了设计模式我们能够更有效的利用面向对象的特性,使得整个软件设计更加灵活、优雅。可是设计模式是基于面向对象的思想而形成的。很多其它的时候关注的是对象层次的东西,在解决对象行为内部问题方面却有些不足。

AOP的出现恰恰就是对面向对象思想做出了完美的补充。

说到AOP,我们就不得不来提一下软件的纵向和横向问题。从纵向结构来看就是我们软件系统的各个模块。它主要负责处理我们的核心业务(比如商品订购、购物车查看);而从横向结构来看,我们差点儿每一个系统又包括一些公共模块(比如权限、日志模块等)。

这些公共模块分布于我们各个核心业务之中(比如订购和查看商品明细的过程都须要检查用户权限、记录系统日志等)。这样一来不仅在开发过程中要处处关注公共模块的处理并且开发后维护起来也是十分麻烦。而有了AOP之后将应用程序中的商业逻辑同对其提供支持的通用服务进行分离,使得开发者能够很多其它的关注核心业务开发。

利用动态代理实现AOP

以下我们就以一个简单的样例来看一下AOP吧!

点击下载源代码:下载

比方说,我们如今要开发的一个应用里面有非常多的业务方法,可是,我们如今要对这种方法的运行做全面监控,或部分监控.或许我们就会在要一些方法运行前进行日志记录,我们写个样例看看我们最简单的解决方式

我们先写一个接口UserManager.java代码例如以下:

publicinterface UserManager {
publicvoid add(String userId, String userName);
}

add方法里面仅仅是将简单的字符串作为參数,而不是实体。勿怪,解说的重点不是这里。我们去写个类实现UserManager接口

publicclass UserManagerImp implements UserManager {

@Override
publicvoid add(String userId, String userName) {
System.out.println("成功运行:UserManagerImpl.add()userId-->>" + userId);
}
}

如今我们要为这个业务方法加上日志记录的业务,我们在不改变原代码的情况下,我们会去怎么做呢?或许,你会去写一个类去实现UserManager接口,并依赖UserManagerImp这个类.代码例如以下:

public class UserManagerProxyimplements UserManager{
private UserManager userManager; public UserManagerProxy(UserManager userManager){
this.userManager= userManager;
}
publicvoid addUser(String userId, String userName) {
System.out.println("start-->>addUser()userId-->>" + userId);
try{
userManager.add(userId,userName); System.out.println("success-->>addUser()");
}catch(Exceptione) {
e.printStackTrace();
System.out.println("error-->>addUser()");
thrownew RuntimeException();
}
}
}

从上面的代码我们能够看出,UserManager
对象是被UserManagerProxy这个所谓的代理所创建的.这样,假设我们以后要把日志记录的功能去掉.那我们仅仅要把得到userManager对象的的详细实现改为UserManager的就能够。

上面的代码 就是对AOP的最简单的实现,可是我们接下来想,假设我们要在非常多业务逻辑之前加日志的话。那么,我们是不是要去写非常多个UserManagerProxy这种类呢.事实上也是一种非常麻烦的事.在jdk1.3以后.jdk跟我们提供了一个API java.lang.reflect.InvocationHandler的类. 这个类能够让我们在JVM调用某个类的方法时动态的为些方法做些什么事.让我们把以上的代码改一下来看看效果.

我们一样的去写一个代理类.仅仅只是.让这个类去实现java.lang.reflect.InvocationHandler接口,代码例如以下:

packagecom.java.drp.pattern;

importjava.lang.reflect.InvocationHandler;
importjava.lang.reflect.Method;
importjava.lang.reflect.Proxy; publicclass LogHandler implements InvocationHandler {
/**
* 要处理的对象(也就是我们要在方法前后加上业务逻辑的对象)
*/
privateObject targetObject; /**
* 动态生成方法被处理过后的对象 (写法固定)
* @param targetObject
* @return
*/
publicObject newProxyInstance(Object targetObject){
this.targetObject= targetObject;
returnProxy.newProxyInstance(targetObject.getClass().getClassLoader(),targetObject.getClass().getInterfaces(), this);
} /**
*要处理的对象中的每一个方法会被此方法送去JVM调用,也就是说,要处理的对象的方法仅仅能通过此方法调用
* 此方法是动态的,不是手动调用的
*/
@Override
publicObject invoke(Object proxy, Method method, Object[] args)
throwsThrowable {
System.out.println("将要运行的方法:"+ method.getName()); System.out.print("将要运行的方法中的參数:");
for(int i = 0; i < args.length; i++) {
System.out.print(args[i]+ " ");
}
System.out.println(); Objectresult = null;
try{
//运行原来的方法之前记录日志
System.out.println(method.getName()+ "Method Start!");
//JVM通过这条语句运行原来的方法(反射机制)
result= method.invoke(targetObject, args); //运行原来的方法之后记录日志
System.out.println(method.getName()+ "Method End!");
}catch (Exception e) {
e.printStackTrace();
throwe;
}
//返回方法返回值给调用者
returnresult;
} }

该段代码的运行流程

执行结果:

将要运行的方法:add

将要运行的方法中的參数:001tch

addMethod Start!

加入用户成功

addMethod End!

从上面的样例我们看出,你的不论什么对象的方法运行之前要加上记录日志的操作都是能够的.LogHandler自己主动去代理运行被代理对象UserManagerImp中的每个方法,通过java.lang.reflect.InvocationHandler接口就把我们的代理对象和被代理对象解藕。

总结

上面简单的介绍了怎样用动态代理的方式实现AOP。主要是帮助大家理解动态代理AOP的大致思路。以便更好的使用AOP工具,而且把AOP应用到实际的面向对象开发。

版权声明:本文博主原创文章。博客,未经同意不得转载。

集装箱学习(两):动手模拟AOP的更多相关文章

  1. [原]容器学习(二):动手模拟AOP

    简单来说,Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架.上文已经介绍模拟IoC实现,这篇文章来动手模拟AOP. AOP简述 面向对象强调"一切皆是对象" ...

  2. [原]容器学习(一):动手模拟spring的IoC

    介绍 学习经典框架的实现原理以及设计模式在其实际中的运用,是非常有必要的,可以让我们更好进行面向对象. 本篇文章就来模拟Spring的IOC功能,明白原理后,可以更好的使用它,进而为进行面向对象提供一 ...

  3. 容器学习(一):动手模拟spring的IoC

    介绍 学习经典框架的实现原理以及设计模式在事实上际中的运用,是很有必要的,能够让我们更好进行面向对象. 本篇文章就来模拟Spring的IOC功能.明确原理后,能够更好的使用它,进而为进行面向对象提供一 ...

  4. 动态代理学习(一)自己动手模拟JDK动态代理

    最近一直在学习Spring的源码,Spring底层大量使用了动态代理.所以花一些时间对动态代理的知识做一下总结. 我们自己动手模拟一个动态代理 对JDK动态代理的源码进行分析 文章目录 场景: 思路: ...

  5. Spring 源码学习笔记10——Spring AOP

    Spring 源码学习笔记10--Spring AOP 参考书籍<Spring技术内幕>Spring AOP的实现章节 书有点老,但是里面一些概念还是总结比较到位 源码基于Spring-a ...

  6. Spring两种实现AOP的方式

    有两种实现AOP的方式:xml配置文件的方式和注解的形式 我们知道通知Advice是指对拦截到的方法做什么事,可以细分为 前置通知:方法执行之前执行的行为. 后置通知:方法执行之后执行的行为. 异常通 ...

  7. python学习两月总结_汇总大牛们的思想_值得收藏

    下面是我汇总的我学习两个月python(version:3.3.2)的所有笔记 你可以访问:http://www.python.org获取更多信息 你也可以访问:http://www.cnblogs. ...

  8. Java动态代理(三)——模拟AOP实现

    以下案例模拟AOP实现 目录结构 接口PersonService package com.ljq.service; public interface PersonService { public vo ...

  9. 为U盘装备Ubuntu工作学习两不误

        题记: 在上一篇文章中,我介绍了让Ubuntu 10.04完美支持Thinkpad小红点Trackpoint.看上去,显得有些不痛不痒,实际上有些同学会因为小红点中键不能正常使用,而放弃在Th ...

随机推荐

  1. Java专项面试训练(一)

    1.在Java中,( )类提供定位本地文件系统,对文件或目录及其属性进行基本操作( D ) A.FileInputStream B.FileReader C.FileWriter D.File解析:F ...

  2. Innobackupex 全备数据库

    对于MySQL数据库的热备.xtrabackup是除了MySQL enterprise backup之外的不二之选. 该工具提供了基于innodb存储引擎的热备.支持全量,增量备份,部分备份,时点恢复 ...

  3. [置顶] 软件设计之道_读书纪要.doc

    本系列的文档都是我读书后的个人纪要,如想了解更多相关内容,请购买正版物.对应的图书可以从我的个人图书列表里找寻:个人毕业后图书列表 1.  每个写代码的人都是设计师,团队里每个人都有责任保证自己的代码 ...

  4. Swift Strings and Characters

    String 是一个有序的字符集合,例如 "hello, world", "albatross".Swift 字符串通过 String 类型来表示,也可以表示为 ...

  5. mock server相关解决方案

    前后端分离之后 前后端分离后, 大家从此进入了所谓的并行开发时代. 一旦完成前后端的(边界)分工, 大家就可以各司其职了. 前端在与后端交互时, 要想有效地提高工作效率, 后端的接口文档就是重中之重了 ...

  6. 【巧妙的模拟】【UVA 10881】 - Piotr's Ants/Piotr的蚂蚁

    </pre></center><center style="font-family: Simsun;font-size:14px;"><s ...

  7. winform —— 常用控件

    1.textbox: 属性:text:    文本selectedtext:         获或设置选中文本canundo:         是否能够撤销 passwordchar:替换字符实现密码 ...

  8. js页面换行与空格

    1.换行 +'<br/>\n': 2.空格 1#JS——输出内容document.write#用于直接向 HTML 输出流写内容.简单的说就是直接在网页中输出内容.1.输出内容用“”括起, ...

  9. PHP学习笔记一

    <html> <head> <title></title> <meta http-equiv="content-type" c ...

  10. ps 网页配图设计

    网站配图设计 蒙太奇 品科软件---网页页面 1橡皮擦来画两图 容合 大橡皮擦擦出来自然 2图放到一个色块中 用剪贴蒙版 3调色阶 装饰下图片  矩形工具  形状  填充 画彩条 超出本框的怎么去掉多 ...