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. sqlserver中的时间比较

    例子: select count(*) from table where DATEDIFF ([second], '2004-09-18 00:00:18', '2004-09-18 00:00:19 ...

  2. diy文件系统上创建文件的流程

    [0]README 0.1) source code are from orange's implemention of a os , and for complete code , please v ...

  3. 图像处理之log---log算子

    在图像中,边缘可以看做是位于一阶导数较大的像素处,因此,我们可以求图像的一阶导数来确定图像的边缘,像sobel算子等一系列算子都是基于这个思想的. 但是这存在几个问题:1. 噪声的影响,在噪声点处一阶 ...

  4. Touch ID和Passcode框架,Apple Watch风格的应用布局

    本文转载至 http://www.cocoachina.com/ios/20141031/10110.html 水平滚动条(artwalk) 测试环境:Xcode 6.0,iOS 8.0     VE ...

  5. IntelliJ idea webstrom Visual Studio Code vscode 设置cmder为默认终端 Terminal

    1.系统环境win10 2.确保环境变量中存在CMDER_ROOT,没有的话新增一个.地址为*:\***\cmder . idea.webstrom:设置中搜索terminal,shell path  ...

  6. windowsphone8.1学习笔记之应用数据(三)

    之前说了如何操作文本文件,如果是图片文件或者其他的二进制文件则需要操作文件的Stream或者Buffer数据.就需要用到DataReader和DataWriter这两个类了,这个的好好的练一下,以后的 ...

  7. PPID=1 runs as a background process, rather than being under the direct control of an interactive user

    https://en.wikipedia.org/wiki/Daemon_(computing) [后台进程,非互动] d 结尾 syslogd 系统日志记录 sshd 响应ssh连接请求 In mu ...

  8. php标准库DirectoryIterator类的操作说明

    <?php $dir = new DirectoryIterator(dirname(__FILE__)); foreach ($dir as $fileInfo) { if ($fileInf ...

  9. linux c编程:gdb的使用

    首先用一个简单的打印字符的程序来做下示例 #include<stdio.h>#include<string.h>void main(){    int i=0;    char ...

  10. Codeforces Round #243 (Div. 1)——Sereja and Two Sequences

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/u012476429/article/details/24798219 题目链接 题意:给两个长度分别 ...