===========================================

    原文链接: 动态代理的两种实现方式(JDK/Cglib) 转载请注明出处!

===========================================

什么是代理模式?(设计模式—代理模式)
  代理模式:在调用处不直接调用目标类进行操作,而是调用代理类,然后通过代理类来调用目标类进行操作。在代理类调用目标类的前后可以添加一些预处理和后处理操作来完成一些不属于目标类的功能。
为什么要使用代理模式?
  通过代理模式可以实现对目标类调用的控制、在目标类调用前/后进行一些不属于目标类的操作,如:数据验证、预处理、后处理、异常处理等
什么是静态代理什么是动态代理?
  静态代理:代理类只能实现对”特定接口的实现类“进行代理
  动态代理:代理类可以实现对多种类的代理
jdk代理和cglib代理区别在哪里?
  jdk动态代理:代理所有“实现的有接口”的目标类
     cglib动态代理:代理任意一个目标类,但对final类和方法无法代理
     不同点:jdk动态代理的目标类必须实现的有接口,因为在调用Proxy.newProxyInstance()的时候需要传入目标类的接口类。而cglib不做此限制。

   下面看代码分析:

定义一个Person接口

package com.zpj.designMode.proxy;

//定义一个Person接口
public interface Person {
public void doWork();
}

添加一个实现类:MrLi

package com.zpj.designMode.proxy;

//添加一个实现类
public class MrLi implements Person { @Override
public void doWork() {
System.out.println("-----doWork");
} }

静态代理:

 添加一个静态代理类Proxy

package com.zpj.designMode.proxy;

//静态代理,代理必须和目标类实现共同的接口
public class Proxy implements Person {
private Person person;// 被代理人 //这里的目标类型决定了该代理类只能代理实现了Person接口的实例,而不能接收其他类型参数,这也就是静态代理的局限性
public Proxy(Person person) {
this.person = person;
} @Override
public void doWork() {
System.out.println("doSomething-----start");
person.doWork();
System.out.println("doSomething-----end");
} }

静态代理测试程序:

package com.zpj.designMode.proxy;

public class Run {
public static void main(String[] args) {
MrLi li = new MrLi();
Proxy proxy = new Proxy(li);
//调用处直接调用代理进行目标方法的操作。
proxy.doWork();
}
}

JDK动态代理:

添加一个代理JDKProxy,该代理实现InvocationHandler接口且覆写invoke方法。

package com.zpj.designMode.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /***
@author Perkins Zhu
@date 2017年3月13日 上午8:41:10
*/
public class JDKProxy implements InvocationHandler { private Object person;// 被代理人 //这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理。但是要注意下面的newProxyInstance()中的参数
public Object getInstance(Object person) {
this.person = person;
//与cglib的区别在于这里构建代理对象的时候需要传入被代理对象的接口对象,第二个参数。而cglib不需要被代理对象实现任何接口即可
return Proxy.newProxyInstance(person.getClass().getClassLoader(), person.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("doSomething---------start");
method.invoke(person, args);
System.out.println("doSomething---------end");
return null;
} }

JDK动态代理测试程序

package com.zpj.designMode.proxy.jdk;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person; /***
* @author Perkins Zhu
* @date 2017年3月13日 上午8:51:31
*/
public class Run { public static void main(String[] args) {
Person person = (Person) new JDKProxy().getInstance(new MrLi());
//注意这里的person不是目标类person,而是代理类person:debug的时候显示null,有'$'标识符
person.doWork();
}
}

Cglib动态代理:

添加一个CglibProxy代理,同时实现MethodInterceptor接口。

package com.zpj.designMode.proxy.cglib;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; /***
* @author Perkins Zhu
* @date 2017年3月13日 上午9:02:54
*/
public class CglibProxy implements MethodInterceptor {
private Object targetObject; // 这里的目标类型为Object,则可以接受任意一种参数作为被代理类,实现了动态代理
public Object getInstance(Object target) {
this.targetObject = target;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(target.getClass());
enhancer.setCallback(this);
//注意该处代理的创建过程
Object proxyObj = enhancer.create();
return proxyObj;// 返回代理对象
} @Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object obj = null;
System.out.println("doSomething---------start");
obj = method.invoke(targetObject, args);
System.out.println("doSomething---------end");
return obj;
} }

Cglib动态代理测试程序

package com.zpj.designMode.proxy.cglib;

import com.zpj.designMode.proxy.MrLi;
import com.zpj.designMode.proxy.Person; /***
@author Perkins Zhu
@date 2017年3月13日 上午9:07:38
*/
public class Run { public static void main(String[] args) {
Person person = (Person)new CglibProxy().getInstance(new MrLi());
person.doWork();
}
}

仔细对比Proxy、CglibProxy和JDKProxy区分静态代理、JDK动态代理和Cglib动态代理的异同点!

-------end

动态代理的两种实现方式(JDK/Cglib)的更多相关文章

  1. Java动态代理的两种实现方式:

    方式一:传统的代理 package cn.hc.domain; import java.lang.reflect.InvocationHandler; import java.lang.reflect ...

  2. java动态代理的两种方法

    动态代理,有两种情况,第一种是有接口的情况下,你可以选择为jdk自带的动态代理的方式来编写程序,但你想要为一个实在的类编写动态代理的方式的话,这时候就必须选择一些开源的lib包,如cglib包,同时还 ...

  3. 动态代理的两种方式,以及区别(静态代理、JDK与CGLIB动态代理、AOP+IoC)

    Spring学习总结(二)——静态代理.JDK与CGLIB动态代理.AOP+IoC   目录 一.为什么需要代理模式 二.静态代理 三.动态代理,使用JDK内置的Proxy实现 四.动态代理,使用cg ...

  4. java动态代理的2种实现方式

    java的动态代理在接java的api上有说明,这里就不写了.我理解的代理: 对特定接口中特定方法的功能进行扩展,这就是代理.代理是通过代理实例关联的调用处理程序对象调用方法. 下面通过一个例子看一下 ...

  5. spring aop提供了两种实现方式jdk和cglib

    Spring AOP使用了两种代理机制:一种是基于JDK的动态代理:另一种是基于CGLib的动态代理.之所以需要两种代理机制,很大程度上是因为JDK本身只提供接口的代理,而不支持类的代理. Sprin ...

  6. Java动态代理的两种实现方法

    注:文章转载自:https://blog.csdn.net/m0_38039437/article/details/77970633 一.代理的概念 动态代理技术是整个java技术中最重要的一个技术, ...

  7. Java实现动态代理的两种方式

    http://m.blog.csdn.net/article/details?id=49738887

  8. JDK动态代理(Proxy)的两种实现方式

    JDK自带的Proxy动态代理两种实现方式 前提条件:JDK Proxy必须实现对象接口 so,创建一个接口文件,一个实现接口对象,一个动态代理文件 接口文件:TargetInterface.java ...

  9. Mybatis系列全解(七):全息视角看Dao层两种实现方式之传统方式与代理方式

    封面:洛小汐 作者:潘潘 一直以来 他们都说为了生活 便追求所谓成功 顶级薪水.名牌包包 还有学区房 · 不过 总有人丢了生活 仍一无所获 · 我比较随遇而安 有些事懒得明白 平日里问心无愧 感兴趣的 ...

随机推荐

  1. 游戏UI框架设计(一) : 架构设计理论篇

    游戏UI框架设计(一) ---架构设计理论篇 前几天(2017年2月)看到一篇文章,国内王健林.马云等大咖们看好的未来十大最有"钱途"产业中,排名第一的就是"泛娱乐&qu ...

  2. [Hadoop] - Win7下提交job到集群上去

    一般我们采用win开发+linux hadoop集群的方式进行开发,使用插件:hadoop-***-eclipse-plugin. 运行程序的时候,我们一般采用run as application或者 ...

  3. 编写一个飞行棋项目(C#)遇到几个问题:

    在写程序中遇到如下问题:如果有人知道,请您一定要指点迷津.小白. 1.在运行暂停功能时,这个暂停功能可以实现,但是无法显示提示信息. case 3: Console.Clear(); Program. ...

  4. JavaScript中国象棋程序(7) - 置换表

    "JavaScript中国象棋程序" 这一系列教程将带你从头使用JavaScript编写一个中国象棋程序.这是教程的第2节. 这一系列共有9个部分: 0.JavaScript中国象 ...

  5. Jquery动态增加行和删除行

    $("#add_5").click(function(){ var str_1="<tr> <td><input type=\"t ...

  6. 为 instance 配置静态 IP - 每天5分钟玩转 OpenStack(157)

    这是 OpenStack 实施经验分享系列的第 7 篇. 传统运维中为服务器配置静态 IP 是再常见不过的了.但在 OpenStack 环境下只能指定 network,IP 都是 Neutron 从 ...

  7. 使用jquery的load方法设计动态加载,并解决被加载页面JavaScript失效问题

    一.问题分析 对于后台系统,相比大家都有所印象,知道其中的布局结构,如图: 在这种布局中我们需要将header,sidebar,footer分开,而且对于中间部分的content内容需要动态变化,即根 ...

  8. 利用IIS和Nginx实现负载均衡

    一直对Nginx反向代理和负载均衡感兴趣,今天在Windows下搭建了一个简单实例.步骤如下: 1.下载Nginx,我下载的是最新的1.11.10版本,地址http://nginx.org/downl ...

  9. Laravel的console使用方法

    适用场景:分析数据(日志) php artisan make:console 你的命令类名 示例: php artisan make:console Check 在\app\Console\Comma ...

  10. 一篇文章为你深度解析HTTPS 协议

    一.前言 微信小程序如期发布,开发者在接入微信小程序过程中,会遇到以下问题: 小程序要求必须通过 HTTPS 完成与服务端通信,若开发者选择自行搭建 HTTPS 服务,那需要自行 SSL 证书申请.部 ...