背景:

研究过设计模式的同胞们都知道代理模式可以有两种实现方案:

1.接口实现(或继承抽象类)

核心代码片段

ProxySubject-->>doOperation()

//dosomething before
realSubject.doOperation()
//dosomething after

2.继承父类

核心代码片段

ProxySubject-->>doOperation()

//dosomething before
super.doOperation()
//dosomething after

总结:

相同点

都可以通过Proxy控制对Target的访问

不同点

1.灵活性

“接口实现”的方式更加灵活,代理类可以代理所有实现了ISubject接口的类;

“继承父类”的方式代理类只能代理它的父类,因为java中只支持单继承

2.可行性

如果Target有直接接口,那么这两种方式都可以;

如果没有实现任何接口,那只能采取“继承父类”的方式了

正文

Java中动态代理对应着也有两种实现方式

1.“接口实现"---JDK Proxy

用到JDK提供的InvocationHandler接口和Proxy类

类之间的关系如下

InvocationHandler接口

用于处理方法请求

Proxy类

用于生成代理对象

代码演示

ISubject接口

public interface ISubject {

	public void showName(String name);
}

RealSubject类

public class RealSubject implements ISubject {

	@Override
public void showName(String name) {
System.out.println(name+"闪亮登场");
} }

LogHandler类

为了更明确的说明动态代理的工作原理,将代理的创建过程放到了LogHandler的外部,即main方法中

public class LogHandler implements InvocationHandler {

	Object target=null;

	public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
Object result=null;
//调用目标对象方法前的逻辑
System.out.println("下面有一个大人物要出现");
//调用目标对象的方法,这句代码将代理与目标类联系了起来
method.invoke(target, args);
//调用目标对象方法后的逻辑
System.out.println("大家鼓掌欢迎");
return result; } }

客户端
类Client

public class Client {

	/**
* @param args
*/
public static void main(String[] args) { LogHandler logHandler=new LogHandler();
logHandler.setTarget(new RealSubject());
//创建代理对象
ISubject proxySubject=(ISubject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(), RealSubject.class.getInterfaces(), logHandler);
System.out.println("-------JDK Proxy-------------");
proxySubject.showName("委座"); } }

执行结果

调用过程时序图

2.“继承父类”---CGLIB

用到了CBLIB提供的Enhancer类和MethodInterceptor接口

类之间的关系如下

需要引入第三方jar包

  • cglib-2.2.jar
  • asm-3.1.jar

Enhancer类

用于创建代理对象

MethodInterceptor接口

用于处理方法请求

代码演示

ISubject接口,RealSubject类同上

LogIntercept类

public class LogIntercept implements MethodInterceptor {
Object target=null; public Object getTarget() {
return target;
} public void setTarget(Object target) {
this.target = target;
} @Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable { Object result=null;
//调用目标对象方法前的逻辑
System.out.println("下面有一个大人物要出现");
//调用目标对象的方法,这句代码将代理与目标类联系了起来
arg3.invoke(target, arg2);
//调用目标对象方法后的逻辑
System.out.println("大家鼓掌欢迎");
return result;
} }

客户端类Client

public class Client {

	/**
* @param args
*/
public static void main(String[] args) { LogIntercept logIntercept=new LogIntercept();
logIntercept.setTarget(new RealSubject());
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(RealSubject.class);
enhancer.setCallback(logIntercept); ISubject proxySubject=(ISubject)enhancer.create();
System.out.println("-------CBLIB-------------");
proxySubject.showName("委座"); } }

调用过程时序图

总结

大家可以看到JDK Proxy和CGLIB这两种动态代理的实现过程是非常相似的,但也有区别

相同点:

  • 都用到了一个接口一个类;
  • 接口用于处理方法调用,类用于创建代理对象

JDK Proxy

InvocationHandler接口

Proxy类

CGLIB

MethodIntercept接口

Enhancer类

不同点:

JDK Proxy

使用目标类的接口创建动态代理

CBLIB

使用目标类的子类创建动态代理

最后

JDK Proxy和CGLIB两种动态代理各有千秋,具体用哪个方案要看具体情况。如果目标类实现了对应接口,两种方案都可以;如果没有实现任何接口则要使用CBLIB。比如Hibernate中的实体类是POJO类,没有实现任何接口,那么要通过代理实现延迟加载就只能采用CGLIB方案了。

动态代理双剑客--JDK Proxy与CGLIB的更多相关文章

  1. Java提高班(六)反射和动态代理(JDK Proxy和Cglib)

    反射和动态代理放有一定的相关性,但单纯的说动态代理是由反射机制实现的,其实是不够全面不准确的,动态代理是一种功能行为,而它的实现方法有很多.要怎么理解以上这句话,请看下文. 一.反射 反射机制是 Ja ...

  2. JDK的动态代理深入解析(Proxy,InvocationHandler)(转)

    JDK的动态代理深入解析(Proxy,InvocationHandler)(转) 一.什么是动态代理 动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实.代理一般会实现它所表示的实际对象的 ...

  3. jdk动态代理和cglib动态代理底层实现原理详细解析(cglib动态代理篇)

    代理模式是一种很常见的模式,本文主要分析cglib动态代理的过程 1. 举例 使用cglib代理需要引入两个包,maven的话包引入如下 <!-- https://mvnrepository.c ...

  4. JDK Proxy和CGLIB Proxy

    动态代理在Java中有着广泛的应用,比如Spring AOP,Hibernate数据查询.测试框架的后端mock.RPC,Java注解对象获取等.静态代理的代理关系在编译时就确定了,而动态代理的代理关 ...

  5. java 动态代理范例 InvocationHandler与Proxy

    java 动态代理范例 InvocationHandler与Proxy,拦截与代理 java.lang.reflect.Proxy,Proxy 提供用于创建动态代理类和实例的静态方法.newProxy ...

  6. java 动态代理模式(jdk和cglib)

    package proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Met ...

  7. 【Java】代理模式,静态代理和动态代理(基于JDK或CGLib)

    当我们需要在一个方法之前或之后添加一段逻辑时,自然会想到使用代理类.代理类帮我们代理了实际类的调用,然后可以在实际调用之前和之后添加一些逻辑,从而不浸入实际类. 拓展:由于代理类能在实际类调用之前和之 ...

  8. java设计模式(一)动态代理模式,JDK与CGLIB分析

    -本想着这个知识点放到Spring Aop说说可能更合适一点,但因为上一篇有所提到就简单分析下,不足之处请多多评论留言,相互学习,有所提高才是关键! 什么是代理模式: 记得有本24种设计模式的书讲到代 ...

  9. 动态代理入门(jdk)

    动态代理就是aop的核心,动态代理简单的就是通过创建一个代理对象,然后把原来的方法增强.很抽象,例子是王道.jdk中提供了动态代理的实现,但是它是针对接口,如果要实现动态代理,需要被代理对象的接口.这 ...

随机推荐

  1. 让magento的validate验证hidden field

    Object.extend(Validation, { isVisible : function(elm) { return true; }, insertAdvice : function(elm, ...

  2. A Bug's Life

    #include<stdio.h> #include<string.h> ],num[]; int find(int x){ int r=x; while(r!=bug[r]) ...

  3. android面试题之五

    二十六.什么情况会导致Force Close ?如何避免?能否捕获导致其的异常? 抛出运行时异常时就会导致Force Close,比如空指针.数组越界.类型转换异常等等. 捕获:可以通过logcat查 ...

  4. Web页面布局方式小结

    Web页面是由块元素组成的,正常情况下块元素一个个按垂直方向排布,构成了页面.可是这样的主要的布局方式绝大多时候不能满足我们的需求,所以各种布局方式应运而生,本文就对这些布局方式做个小结. 1.元素漂 ...

  5. 【Samza系列】实时计算Samza中文教程(二)——概念

    希望上一篇背景篇让大家对流式计算有了宏观的认识,本篇依据官网是介绍概念,先让我们看看有哪些东西呢?     概念一:Streams     Samza是处理流的.流则是由一系列不可变的一种相似类型的消 ...

  6. apache的keepalive和keepalivetimeout

    在APACHE的httpd.conf中,KeepAlive指的是保持连接活跃,类似于Mysql的永久连接.换一句话说,如果将KeepAlive设置为On,那么来自同一客户端的请求就不需要再一次连接,避 ...

  7. Asp.net MVC5中Html.DropDownList的使用

    一.静态下拉列表项的绑定 在下拉列表中绑定静态项,我们可以通过 SelectListItem 的集合作为数据源的下拉列表. @Html.DropDownList("dropRoles&quo ...

  8. iOS9基础知识(OC)笔记

    1月16日 Objective  C(20世纪80年代初) 一.OC语言概述 1.1985年,Steve  Jobs成立了NeXT公司 2.1996年,12月20日,苹果公司宣布收购了NeXT  ...

  9. ‘Microsoft.Jet.OLEDB.4.0’ provider is not registered

    正如以下msdn论坛所述,Microsoft.Jet.OLEDB.4.0只有32bit,所以我们必须compile application to x86 platform. http://social ...

  10. Populating Next Right Pointers in Each Node,Populating Next Right Pointers in Each Node II

    Populating Next Right Pointers in Each Node Total Accepted: 72323 Total Submissions: 199207 Difficul ...