一、代理模式:

静态代理、动态代理

动态代理和静态代理区别??

解析:静态代理需要手工编写代理类,代理类引用被代理对象。

动态代理是在内存中构建的,不需要手动编写代理类

代理的目的:是为了在原有的方法上进行增强。

动态代理的两种方式:JDK动态代理与CGLIB代理
默认情况下,Spring AOP的实现对于接口来说就是使用的JDK的动态代理来实现的,而对于类的代理使用CGLIB来实现。

二、静态代理

①定义接口 Subject并添加方法:

public interface Subject {
public void request();
}

② 定义接口的实现类 RealSubject并实现该接口,重写方法--被代理对象

public class RealSubject implements Subject{public void request() {System.out.println("真实主题内容");}

③定义接口的实现类ProxySubject并实现该接口重写方法。自定义属性RealSubject,调用request方法,在这里进行增强

public class ProxySubject implements Subject{private RealSubject real;public void request() {System.out.println("===before===");//调用request()
    real.request();System.out.println("===after===");}public RealSubject getReal() {return real;}public void setReal(RealSubject real) {this.real = real;}

④测试类: 

分别创建出被代理对象和代理对象,执行方法

public class ProxyTest {
//静态代理
   @Testpublic void test01(){//准备一个真实主题,被代理对象RealSubject real=new RealSubject();//创建一个代理对象ProxySubject proxy=new ProxySubject();proxy.setReal(real);proxy.request();
}

执行效果:

可以看出静态代理类有一个缺点:当如果接口加一个方法,所有的实现类和代理类里都需要做个实现。这就增加了代码的复杂度。动态代理就可以避免这个缺点。


三、动态代理

1.1、JDK动态代理:

本质:在内存中构建接口实现类

特点:被代理对象必须有接口 

JDK提供了java.lang.reflect.Proxy类来实现动态代理的,可通过它的newProxyInstance来获得代理实现类。同时对于代理的接口的实际处理,是一个java.lang.reflect.InvocationHandler,它提供了一个invoke方法供实现者提供相应的代理逻辑的实现。可以对实际的实现进行一些特殊的处理,像Spring AOP中的各种advice。下面来看看如何使用。

定义接口IUserDao:

public interface IUserDao {public String add();public String edit();
}

定义接口实现类,实现某接口,并重写该方法:

public String add() {System.out.println("==add===");return "我是add";}public String edit() {System.out.println("===edit===");return "edit";}

测试类:(重点)  

实现效果:

可以由源码可见如何生成代理类的:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h) throws IllegalArgumentException {if (h == null) {throw new NullPointerException();}final Class<?>[] intfs = interfaces.clone();final SecurityManager sm = System.getSecurityManager();if (sm != null) {checkProxyAccess(Reflection.getCallerClass(), loader, intfs);}// 这里是生成class的地方Class<?> cl = getProxyClass0(loader, intfs);// 使用我们实现的InvocationHandler作为参数调用构造方法来获得代理类的实例try {final Constructor<?> cons = cl.getConstructor(constructorParams);final InvocationHandler ih = h;if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {return AccessController.doPrivileged(new PrivilegedAction<Object>() {public Object run() {return newInstance(cons, ih);}});} else {return newInstance(cons, ih);}} catch (NoSuchMethodException e) {throw new InternalError(e.toString());}}
其中newInstance只是调用Constructor.newInstance来构造相应的代理类实例,这里重点是看getProxyClass0这个方法的实现:private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) { // 代理的接口数量不能超过65535if (interfaces.length > 65535) { throw new IllegalArgumentException("interface limit exceeded"); } // JDK对代理进行了缓存,如果已经存在相应的代理类,则直接返回,否则才会通过ProxyClassFactory来创建代理 return proxyClassCache.get(loader, interfaces); 

可以看到,动态生成的代理类有如下特性:
   1) 继承了Proxy类,实现了代理的接口,由于java不能多继承,这里已经继承了Proxy类了,不能再继承其他的类,所以JDK的动态代理不支持对实现类的代理,只支持接口的代理。
   2) 提供了一个使用InvocationHandler作为参数的构造方法。
   3) 生成静态代码块来初始化接口中方法的Method对象,以及Object类的equals、hashCode、toString方法。
   4) 重写了Object类的equals、hashCode、toString,它们都只是简单的调用了InvocationHandler的invoke方法,即可以对其进行特殊的操作,也就是说JDK的动态代理还可以代理上述三个方法。


1.2、cglib动态代理:

JDK实现动态代理需要实现类通过接口定义业务方法,对于没有接口的类,如何实现动态代理呢,这就需要cglib了。cglib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用  

创建被代理的类:

public class UserService {
public void delete(){System.out.println("delete ok!!!");
}
}

测试类:(重点)  

该类实现了创建子类的方法与代理的方法。SuperClass方法通过入参即父类的字节码,通过扩展父类的class来创建代理对象。intercept()方法拦截所有目标类方法的调用,obj表示目标类的实例,method为目标类方法的反射对象,args为方法的动态入参,proxy为代理类实例。proxy.invoke(obj, args)通过代理类调用父类中的方法 !

实现效果:


四、AOP基本术语:

AOP Aspect Oriented Programming 面向切面编程

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

面向对象编程是从【静态角度】考虑程序的结构,而面向切面编程是从【动态角度】考虑程序运行过程。
AOP底层,就是采用【动态代理】模式实现的。采用了两种代理:JDK动态代理和CGLIB动态代理。

基本术语(一些名词): 
(1)切面(Aspect)
切面泛指[*交叉业务逻辑*]。事务处理和日志处理可以理解为切面。常用的切面有通知(Advice)与顾问(Advisor)。实际就是对主业务逻辑的一种增强。

(2)织入(Weaving)
织入是指将切面代码插入到目标对象的过程。代理的invoke方法完成的工作,可以称为织入。

(3) 连接点(JoinPoint) 
连接点是指可以被切面织入的方法。通常业务接口的方法均为连接点

(4)切入点(PointCut)
切入点指切面具体织入的方法
注意:被标记为final的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。

(5)目标对象(Target)
目标对象指将要被增强的对象。即包含主业务逻辑的类的对象。

(6)通知(Advice) 
通知是切面的一种实现,可以完成简单的织入功能。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是执行之后执行等。切入点定义切入的位置,通知定义切入的时间。

(7)顾问(Advisor)
顾问是切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。

转载于:https://www.cnblogs.com/WuXuanKun/p/6001710.html

Spring代理模式及AOP基本术语相关推荐

  1. Spring:代理模式

    一.概述 代理模式分为静态代理以及动态代理,属于23中设计模式之一.动态代理是SpringAop的底层.代理的概念如下图所示: 二. 静态代理 上图角色分析: 抽象角色:一般会使用接口或者抽象类来解决 ...

  2. Spring AOP 概念及动态代理模式

    Spring AOP 概念及动态代理模式 文章目录 Spring AOP 概念及动态代理模式 1 AOP 的概念及相关术语 2 AOP 作用 3 AOP 原理概述 3.1 JDK 动态代理(Proxy ...

  3. Spring源码学习笔记:经典设计模式之代理模式

    1.博客内容均出自于咕泡学院架构师第三期 2.架构师系列内容:架构师学习笔记(持续更新) 0.代理模式(Proxy Pattern) 指为其他对象提供一种代理,以控制对这个对象的访问.代理对象在客户端 ...

  4. [设计模式] - 代理模式(静态代理与动态代理)

    文章目录 一.代理模式简介 1. 什么是代理模式 2. 简单举例 二.代理模式的设计思路 1. 代理模式的构成 1. 静态代理 2. 动态代理 (1)接口代理 (2)Cglib代理 三. 代理模式总结 ...

  5. 动态代理——》AOP —— Spring 中的 AOP||AOP 相关术语||学习 spring 中的 AOP 要明确的事

    AOP 概述 什么是 AOP       AOP:全称是 Aspect Oriented Programming 即:面向切面编程 AOP 的作用及优势 作用: 在程序运行期间,不修改源码对已有方法进 ...

  6. 设计模式:代理模式是什么,Spring AOP还和它有关系?

    接着学习设计模式系列,今天讲解的是代理模式. 定义 什么是代理模式? 代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用.它包含了三个角色: Subject: ...

  7. Spring AOP 代理模式

    记录几篇关于AOP & 代理模式 的博客,写的非常好,感谢作者分享! Java中的代理模式--静态代理以及分析静态代理的缺点 Java中动态代理的两种方式JDK动态代理和cglib动态代理以及 ...

  8. 代理模式和Spring的AOP(持续更新)

    代理模式 代理模式为SpringAOP的底层实现,分为静态代理和动态代理 角色分析: 抽象角色:使用接口或者抽象类 真实角色:被代理的角色 代理角色:代理真实角色,代理后增加一些附属操作 客户访问代理 ...

  9. Spring AOP的作用,动态代理模式

    AOP即面向切面编程.AOP是基于代理模式的. 代理模式: 当我们需要修改一个类,在类中加入代码时,为了不破坏这个类的封装性.可以使用代理模式,建立一个代理类. 比如:修改需求,在调用UserCont ...

最新文章

  1. SpringBatch学习一个Demo项目
  2. 论坛报名 | AI赋能未来交通
  3. VS2019安装Image Watch与失败解决方法
  4. php 位运算与权限,PHP中的二进制位运算和权限存储
  5. #ifndef HeaderName_h #define HeaderName_h #endif 使用详解
  6. Win-MASM64汇编语言-通用寄存器AX/BX/CX/DX/SI/DI/BP
  7. 3Y叔的clusterProfiler-book阅读Chapter 3 Universal enrichment analysis
  8. 方立勋_30天掌握JavaWeb_回顾复习
  9. sai笔记4-加高光/图层切换颜色
  10. golang 使用map处理多级json后输出map中的数组
  11. mutual information matlab,Mutual information and Normalized Mutual information 互信息和标准化互信息...
  12. python批量处理图片颜色反转_Python批量处理图片
  13. 【Grafana】【一】Grafana 简介
  14. 华为服务器bios系统,华为服务器bios配置详解
  15. Python平板电脑数据分析-课程大作业-部分源码
  16. 如何做用户画像分析?
  17. 使用Java-Maven操作MongoDB增删改查
  18. android字体带下划线
  19. 当访问文件时提示文件夹访问被拒绝怎么办
  20. Matplotlib 绘制圆环图的两种方法!

热门文章

  1. word中如何优雅的显示代码
  2. linux上设置svn账户权限设置密码,Linux:如何在svn中设置“全局”用户/密码/组文件...
  3. ios上传图片 java_iOS ASIFormDataRequest上传图片 前后台代码
  4. 一个“想忘带东西都难”的出行指南
  5. mqtt实例 php_php搭建MQtt协议服务
  6. 九宫怎么排列和使用_别人家连客厅茶几都不要了,你却还在纠结挂画怎么挂
  7. python是个啥玩意儿_Pythonic到底是什么玩意儿?
  8. java 集合 总结 表_java 列表与集合总结
  9. DynamicFusion: Reconstruction and Tracking of Non-rigid scenes in real-time
  10. install texlive-full on ubuntu