1.接口

public interface Hello {

    public void sayHello();
}

2.实例类

public class Hello2 {
public void sayHello() {
System.out.println("hello world2!");
}
}
public class Hello3 extends Hello2{

}
public class HelloImpl implements Hello{

    @Override
public void sayHello() {
System.out.println("hello world!");
}
}

3.JDK动态代理

ublic class JdkTest implements InvocationHandler{

    private Object object;

    @SuppressWarnings("unchecked")
public <T> T bind(Object obj){
this.object = obj;
return (T)Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
} @Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("before sayHello");
method.invoke(object, null);
System.out.println("after sayHello");
return null;
} public static void main(String[] args) {
JdkTest test = new JdkTest();
Hello hello = test.bind(new HelloImpl());
hello.sayHello();
} }

4.cglib动态代理

public class CglibTest implements MethodInterceptor{

    private Object obj;

    /**
* 普通接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:36:10
*/
public <T> T instance(T obj){
this.obj = obj;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.obj.getClass());
enhancer.setCallback(this);
return (T)enhancer.create();
} @Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("before sayHello");
arg3.invoke(obj, arg2);
System.out.println("after sayHello");
return null;
} /**
* 无接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:35:58
*/
public <T> T instanceObject(T obj){
T t = (T)Enhancer.create(obj.getClass(),new MethodInterceptor(){ @Override
public Object intercept(Object arg0, Method arg1, Object[] arg2,
MethodProxy arg3) throws Throwable {
System.out.println("hello2 proxy");
return arg3.invokeSuper(arg0, arg2);
} });
return t; } /**
* 无接口类代理
* @author tomsnail
* @date 2015年4月2日 上午10:35:58
*/
public <T> T instanceSuperObject(T obj){
T t = (T)Enhancer.create(obj.getClass(),NoOp.INSTANCE);//无任何代理时,调用父类方法实现
return t; } public static void main(String[] args) {
CglibTest test = new CglibTest();
Hello hello = test.instance(new HelloImpl());
hello.sayHello();
Hello2 hello2 = test.instanceObject(new Hello2());//无接口类的动态代理
hello2.sayHello(); Hello2 hello3 = test.instanceSuperObject(new Hello3());//子类没有重写父类方法的动态代理
hello3.sayHello(); } }

5.小小总结一下

JDK的动态代理只能通过接口进行处理,如果没有接口的,会很难处理。cglib没有这一限制。

还有就是性能,我看见一篇网上已经有了对比,在jdk7/8与cglib相比,反而jdk的性能很好,见http://www.cnblogs.com/haiq/p/4304615.html

重学JAVA基础(三):动态代理的更多相关文章

  1. 重学 Java 设计模式:实战代理模式「模拟mybatis-spring中定义DAO接口,使用代理类方式操作数据库原理实现场景」

    作者:小傅哥 博客:https://bugstack.cn 沉淀.分享.成长,让自己和他人都能有所收获! 一.前言 难以跨越的瓶颈期,把你拿捏滴死死的! 编程开发学习过程中遇到的瓶颈期,往往是由于看不 ...

  2. Java基础-JDK动态代理

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

  3. Java基础-CGLIB动态代理

    JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继 ...

  4. Java基础加强——动态代理

    代理模式: 为其他对象提供一种代理以控制对这个对象的访问. 代理模式主要分为两类: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了.  ...

  5. Java基础-jdk动态代理与cglib动态代理区别

    JDK动态代理 此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑. 代理模式在实际使用时需要指定具体的目标对象 ...

  6. 重学JAVA基础(八):锁的基本知识

    1.线程状态 如上图,当我们新建一个线程,并start后,其实不一定会马上执行,因为只有操作系统调度了我们的线程,才能真正进行执行,而操作系统也随时可以运行其他线程,这时线程又回到可运行状态.这个过程 ...

  7. 重学JAVA基础(二):Java反射

        看一下百度的解释:       JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息     ...

  8. 重学JAVA基础(五):面向对象

    1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; ...

  9. 重学JAVA基础(一):PATH和CLASSPATH

    我想大多数Java初学者都会遇到的问题,那就是怎么配置环境,执行java -jar xxx.jar  都会报NoClassDefFindError,我在最开始学习的时候,也遇到了这些问题. 1.PAT ...

随机推荐

  1. 【puppeteer+Node.js】学习

    总结了一下有关puppeteer的学习的网站,以后还会继续更新 puppeteer 介绍 Puppeteer是一个通过DevTools Protocol控制headless chromium的高级no ...

  2. mongodb的mongod.lock文件及oplog文件

    在mongodb的启动时,在数据目录下,会生成一个mongod.lock文件.如果在正常退出时,会清除这个mongod.lock文件,若要是异常退出,在下次启动的时候,会禁止启动,从而保留一份干净的一 ...

  3. markdownPad2 绿色破解版安装

    markdownpad2,默认为markdown传统风格,不能编辑分行的代码段,可以在设置里改为Github 风格,但需要付费激活,以下是绿色安装包,附激活方法 下载地址 https://pan.ba ...

  4. 基于Apache POI 向xlsx写入数据

    [0]写在前面 0.1) these codes are from 基于Apache POI 的向xlsx写入数据 0.2) this idea is from http://cwind.iteye. ...

  5. Hadoop常见异常及其解决方式

    1.Shell$ExitCodeException 现象:执行hadoop job时出现例如以下异常: 14/07/09 14:42:50 INFO mapreduce.Job: Task Id : ...

  6. 在安装ubuntu时,卡在启动画面

    在我安装ubuntu时发生的情况,记录下来希望能帮助到需要帮助的朋友. 我先后尝试16.04与14.05两个版本的Ubuntu系统,方法均为:https://www.ubuntu.com/downlo ...

  7. 从symbol link和hard link 到 unlink函数的一点记录

    之前一直对Linux的文件类型中的 “l” 类型的了解不是很深入,最近经过“圣经”指点,略知一二,在此先记录一下,以便以后查阅,之后会对文件和目录.文件I/O这部分再扩充. 首先需明确,Unix在查阅 ...

  8. EasyNVR RTSP转RTMP-HLS流媒体服务器前端构建之:通过接口获取实时信息

    对于动态网站,要实时更新网站的信息,通过接口来获取实时信息是一个必不可少的部分.EasyNVR可以接入IPC等前端设备,必须要实时获取到对应的IPC实时信息进行展示. 本篇主要说明Ajax来获取数据. ...

  9. MongoDB C#驱动:

    MongoDB C#驱动: http://xiaosheng.me/2016/09/15/article24 http://www.cnblogs.com/wuhuacong/p/5098348.ht ...

  10. android菜鸟学习笔记5----第一个android程序

    程序功能:点击一个按钮,然后弹出一个提示信息 Step 1:在eclipse中新建一个android application project,在创建过程中不勾选create activity,这样就创 ...