AOP
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

名称含义

[编辑](javascript:?

Aspect Oriented Programming(AOP)是较为热门的一个话题。AOP,国内大致译作“面向切面编程”。

“面向切面编程”,这样的名字并不是非常容易理解,且容易产生一些误导。有些人认为“OOP/OOD11即将落伍,AOP是新一代软件开发方式”。显然,发言者并没有理解AOP的含义。Aspect,的确是“方面”的意思。不过,汉语传统语义中的“方面”,大多数情况下指的是一件事情的不同维度、或者说不同角度上的特性,比如我们常说:“这件事情要从几个方面来看待”,往往意思是:需要从不同的角度来看待同一个事物。这里的“方面”,指的是事物的外在特性在不同观察角度下的体现。而在AOP中,Aspect的含义,可能更多的理解为“切面”比较合适。

可以通过预编译方式和运行期动态代理实现在不修改源代码的情况下给程序动态统一添加功能的一种技术。AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。

在Spring中提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

主要功能

日志记录,性能统计,安全控制,事务处理,异常处理等等。

主要意图

将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

AOP/OOP

区分

AOP、OOP在字面上虽然非常类似,但却是面向不同领域的两种设计思想。OOP(面向对象编程)针对业务处理过程的实体及其属性和行为进行抽象封装,以获得更加清晰高效的逻辑单元划分。

而AOP则是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合性的隔离效果。这两种设计思想在目标上有着本质的差异。

上面的陈述可能过于理论化,举个简单的例子,对于“雇员”这样一个业务实体进行封装,自然是OOP/OOD的任务,我们可以为其建立一个“Employee”类,并将“雇员”相关的属性和行为封装其中。而用AOP设计思想对“雇员”进行封装将无从谈起。

同样,对于“权限检查”这一动作片断进行划分,则是AOP的目标领域。而通过OOD/OOP对一个动作进行封装,则有点不伦不类。

换而言之,OOD/OOP面向名词领域,AOP面向动词领域。

关系

很多人在初次接触 AOP 的时候可能会说,AOP 能做到的,一个定义良好的 OOP 的接口也一样能够做到,我想这个观点是值得商榷的。AOP和定义良好的 OOP 的接口可以说都是用来解决并且实现需求中的横切问题的方法。但是对于 OOP 中的接口来说,它仍然需要我们在相应的模块中去调用该接口中相关的方法,这是 OOP 所无法避免的,并且一旦接口不得不进行修改的时候,所有事情会变得一团糟;AOP 则不会这样,你只需要修改相应的 Aspect,再重新编织(weave)即可。 当然,AOP 也绝对不会代替 OOP。核心的需求仍然会由 OOP 来加以实现,而 AOP 将会和 OOP 整合起来,以此之长,补彼之短。

(https://upload-images.jianshu.io/upload_images/15384450-d0ef6c94dc19f331.png?imageMogr2/auto-orient/strip|imageView2/2/w/1240)

##动态代理+反射

代理的方式:1.静态代理 2.JDK动态代理 3.Cglib Spring AOP所使用的动态代理方式

CGLIB中的动态代理是JDK proxy的一个很好的补充,在JDK中实现代理时,要求代理类必须是继承接口的类,因为JDK最后生成的proxy class其实就是实现了被代理类所继承的接口并且继承了java中的Proxy类,通过反射找到接口的方法,调用InvocationHandler的invoke 方法实现拦截。CGLIb中最后生成的proxy class是一个继承被代理类的class,通过重写被代理类中的非final的方法实现代理。总结为:
JDK proxy:代理类必须实现接口
CGLIB: 代理类不能是final,代理的方法也不能是final(继承限制)

1、静态代理

1、静态代理

静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口,被代理类,代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。

2、静态代理简单实现

根据上面代理模式的类图,来写一个简单的静态代理的例子。我这儿举一个比较粗糙的例子,假如一个班的同学要向老师交班费,但是都是通过班长把自己的钱转交给老师。这里,班长就是代理学生上交班费,

班长就是学生的代理。

首先,我们创建一个Person接口。这个接口就是学生(被代理类),和班长(代理类)的公共接口,他们都有上交班费的行为。这样,学生上交班费就可以让班长来代理执行。

/*** 创建Person接口* @author Gonjan*/
public interface Person {//上交班费void giveMoney();
}

Student类实现Person接口。Student可以具体实施上交班费的动作。

public class Student implements Person {private String name;public Student(String name) {this.name = name;}@Overridepublic void giveMoney() {System.out.println(name + "上交班费50元");}
}

StudentsProxy类,这个类也实现了Person接口,但是还另外持有一个学生类对象,由于实现了Peson接口,同时持有一个学生对象,那么他可以代理学生类对象执行上交班费(执行giveMoney()方法)行为。

/*** 学生代理类,也实现了Person接口,保存一个学生实体,这样既可以代理学生产生行为* @author Gonjan**/
public class StudentsProxy implements Person{//被代理的学生Student stu;public StudentsProxy(Person stu) {// 只代理学生对象if(stu.getClass() == Student.class) {this.stu = (Student)stu;}}//代理上交班费,调用被代理学生的上交班费行为public void giveMoney() {stu.giveMoney();}
}

下面测试一下,看如何使用代理模式:

public class StaticProxyTest {public static void main(String[] args) {//被代理的学生张三,他的班费上交有代理对象monitor(班长)完成Person zhangsan = new Student("张三");//生成代理对象,并将张三传给代理对象Person monitor = new StudentsProxy(zhangsan);//班长代理上交班费monitor.giveMoney();}
}

运行结果:

这里并没有直接通过张三(被代理对象)来执行上交班费的行为,而是通过班长(代理对象)来代理执行了。这就是代理模式。

代理模式最主要的就是有一个公共接口(Person),一个具体的类(Student),一个代理类(StudentsProxy),代理类持有具体类的实例,代为执行具体类实例方法。上面说到,代理模式就是在访问实际对象时引入一定程度的间接性,因为这种间接性,可以附加多种用途。这里的间接性就是指不直接调用实际对象的方法,那么我们在代理过程中就可以加上一些其他用途。就这个例子来说,加入班长在帮张三上交班费之前想要先反映一下张三最近学习有很大进步,通过代理模式很轻松就能办到

可以看到,只需要在代理类中帮张三上交班费之前,执行其他操作就可以了。这种操作,也是使用代理模式的一个很大的优点。最直白的就是在Spring中的面向切面编程(AOP),我们能在一个切点之前执行一些操作,在一个切点之后执行一些操作,这个切点就是一个个方法。这些方法所在类肯定就是被代理了,在代理过程中切入了一些其他操作。

1.动态代理(JDK)

java.lang.reflect
接口 InvocationHandler

1.新建一个Dog.java

package com.foreknow.proxy;public interface Dog {public void info();
public void run();
}

2.DogImpl.java 实现类

package com.foreknow.proxy;
/*** 目标对象* @author Administrator**/
public class DogImpl implements Dog{@Overridepublic void info() {System.out.println("info....");}@Overridepublic void run() {System.out.println("run....");}}

3.DogInterceptor.java 常见一个拦截器 在目标对象前后添加

package com.foreknow.proxy;
/*** 拦截器* 拦截某一个方法之前或者之后的操作方法* @author Administrator**/
public class DogInterceptor {public void method1(){System.out.println("method1");}public void method2(){System.out.println("method2");}
}
  1. ProxyHandler.java 利用放射接口实现
package com.foreknow.proxy;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;public class ProxyHandler  implements InvocationHandler{//目标对象   相当于切入点Object target;DogInterceptor di=new DogInterceptor();public void setTarget(Object target) {this.target = target;}@Override//Method method  参数  我想拦截这个方法  首先我的获取这个方法public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//首先得获得切入点    然后在这个切入点前  后 操作//第一   获取到的目标对象  第二个 是参数if(method.getName().equals("info")){di.method1();method.invoke("target", args);//调用info方法di.method2();}else{method.invoke("target", args);//否则调用run方法}return null;}}

5.创建一个代理工厂MyproxyFacotory.java

package com.foreknow.proxy;import java.lang.reflect.Proxy;/*** 创建一个工厂类 * Proxy是动态在程序运行是生成的类  当然 Proxy不会代替你去做实际的工作,是由动态代理ProxyHandler完成实际的工作* @author Administrator**/
public class MyproxyFacotory {public  static Object getProxy(Object obj){ProxyHandler h= new ProxyHandler();//设置目标对象h.setTarget(obj);//一个  是代理类的对象  也就是dogimpl的对象getClassLoader()类的加载器    //第二个参数 获取代理类的接口//获取核心代理类的对象  new 出来的H return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), h);}
}

6.测试类Test.java

package com.foreknow.proxy;public class Test {public static void main(String[] args) {//创建代理的对象Dog dogTarger=new DogImpl();Object proxy=MyproxyFacotory.getProxy(dogTarger);Dog dog=null;//instanceof  看看是否属于Dog这个接口 if(proxy instanceof Dog){dog =(Dog) proxy;}dog.info();dog.run();}
}

输出结果

method1
info....
method2
run....

AOP处理事务静、动态代理(jdk方法)相关推荐

  1. 动态代理jdk和cglib区别、注意事项(private,static,final)、spring aop原理

    文章目录 一.代理简聊 二.静态代理 三.动态代理 1.jdk动态代理 2.cglib动态代理 四.动态代理总结.注意事项 1.jdk动态代理与cglib的区别. 2.注意事项及分析. 五.aop原理 ...

  2. Spring AOP的两种动态代理方式的原理和实现(JDK和CGLIB)

    代理机制 Spring 的AOP 部分使用使用JDK动态代理,部分使用CGLIB来为目标对象创建代理.如果被代理的目标对象实现了至少一个接口,则会使用JDK动态代理:如果目标对象没有实现任何接口,则会 ...

  3. Spring AOP【AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别】

    Spring AOP[AOP的基本实现与动态代理JDK Proxy 和 CGLIB区别]

  4. jdk动态代理invoke方法自动运行原因

    invoke 方法介绍 想要知道 invoke方法为什么会自动调用我们先要来了解一下这个方法 public interface InvocationHandler { public Object in ...

  5. Spring 容器AOP的实现原理——动态代理

    本文来自极客学院 Spring 容器AOP的实现原理--动态代理 之前写了一篇关于IOC的博客--<Spring容器IOC解析及简单实现>,今天再来聊聊AOP.大家都知道Spring的两大 ...

  6. 使用 cglib_java动态代理(JDK和CGLIB原理解析与使用)

    CGLIB的动态代理 原理 代理为控制要访问的目标对象提供了一种途径.当访问对象时,它引入了一个间接的层.JDK自从1.3版本开始,就引入了动态代理,并且经常被用来动态地创建代理.JDK的动态代理用起 ...

  7. JAVA 进阶篇 动态代理 JDK动态代理和CGlib动态代理

    JDK动态代理和CGlib动态代理 JDK动态代理: 利用反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理. CGlib动态代理: 利用ASM(开源的Java ...

  8. Java两种动态代理JDK动态代理和CGLIB动态代理

    目录 代理模式 JDK动态代理 cglib动态代理 测试 代理模式 代理模式是23种设计模式的一种,他是指一个对象A通过持有另一个对象B,可以具有B同样的行为的模式.为了对外开放协议,B往往实现了一个 ...

  9. java动态代理(JDK和cglib)详解

    JAVA的动态代理  代理模式  代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等.代理类与委 ...

最新文章

  1. 修改ceph-disk源码,增加指定ceph.conf部署osd的功能
  2. 让Hinton后悔投少了的AI公司:吴恩达弟子创办,李飞飞也是投资人
  3. Volley框架学习
  4. 装了mysql但是服务里没有反应_Mysql安装后在服务里找不到和服务启动不起来的解决方法...
  5. 计算机一级应用考试题,办公软件应用计算机一级考试试题
  6. ad域用户和计算机搭建,Windows Server 6分钟搭建AD域
  7. 组建一个局域网一般会用到哪些设备_朋友私信一个简单的问题:端口和网关到底有什么区别?...
  8. BizTalk开发系列(二十二) 开发自定义Map Functoid
  9. BZOJ2194: 快速傅立叶之二 (FFT)
  10. c#+asp.net如何删除指定路径下的文件和文件夹
  11. MESSL(maven + extjs + spring portlet mvc + spring web flow + liferay )整合架构 7
  12. 【转】数据库常用面试题
  13. 终于注册csdn博客了!
  14. 格式化报错a bad sector is being found while format this partition
  15. gulp打包报错 “Error: Unhandled ‘error‘ event at new JS_Parse_Error”
  16. 小米路由器 内核 linux,小米路由器配置ssh登入方法教程
  17. 零零信安:攻击面管理(ASM)技术详解和实现
  18. Python3 正则表达式
  19. Windows10:CIFS服务的开启
  20. [Fabric] 第11章 Fabric CA应用与配置

热门文章

  1. Q110:PBRT-V3十大基类对应的继承关系
  2. 数据挖掘-二手车价格预测 Task04:建模调参
  3. 物联卡认识易陷入的几大误区
  4. mysql查询id为5的数据类型_MySql学习05---数据类型
  5. 鸿蒙系统适配机型_余承东:华为手机鸿蒙系统体验比安卓更好,主流应用已完成适配...
  6. Scala中如何优雅的处理Null
  7. java 处理unicode_java处理unicode字符
  8. C++ 变量、常量、符号常量
  9. 研究:三分之一英国人或因机器人“丢饭碗”
  10. YARN REST API