重学JAVA基础(三):动态代理

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

时间: 2024-07-31 21:48:53

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

Java基础:动态代理在RPC框架中应用

转载请注明出处:jiq?钦's technical Blog RPC,远端过程调用.就是调用远端机器上的方法. 原理其实很简单,就是客户端上运行的程序在调用对象方法时,底层将针对该方法的调用转换为TCP/HTTP请求,发送到远端服务器,远端服务器监听固定端口,收到这个TCP/HTTP请求后会解析出相关信息,包括客户端想要调用哪个类的哪个方法,参数是什么等,然后进行对应的调用,将调用结果再通过数据包发回即可. RPC中一般会有一些"契约"的概念,即客户端和服务端双方约定好的接口,表明服务

Java基础加强——动态代理

代理模式: 为其他对象提供一种代理以控制对这个对象的访问. 代理模式主要分为两类: 静态代理:由程序员创建或特定工具自动生成源代码,再对其编译.在程序运行前,代理类的.class文件就已经存在了.  动态代理:在程序运行时,运用反射机制动态创建而成 1.静态代理相对好理解一些,来看下面的代码: 接口 Count.java /** * 账户接口 * @author jiangbei01 * */ public interface Count { void add(); void update();

JAVA基础_动态代理的基本API

JDK动态代理 代理类中使用的方法需要声明在接口中 需要得到目标类的对象 Cglib包中的动态代理 import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; import org.junit.Test; import java.lang.reflect.InvocationHandler; import java.l

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

1.线程状态 如上图,当我们新建一个线程,并start后,其实不一定会马上执行,因为只有操作系统调度了我们的线程,才能真正进行执行,而操作系统也随时可以运行其他线程,这时线程又回到可运行状态.这个过程是操作系统控制的,不是我们能控制的.我们能控制的是将线程变为blocked,并从blocked变为runable状态. 在以前实验的wait和notify中,我当时并没有注意到notify后会进行锁阶段,以为notify后直接进入runable状态,等待操作系统调度.  从上面的图中可以看到,我们n

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

看一下百度的解释: JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法:对于任意一个对象,都能够调用它的任意一个方法和属性:这种动态获取的信息    以及动态调用对象的方法的功能称为java语言的反射机制. 先看一下一个例子: 这是最简单的反射使用方法,通过反射来调用类的方法. 下面通过一个需求来做反射实验:有3种人类(黄,白,黑),分别继承于Human类,都有人类的共同操作Behaviour /** * 行为,区别于动物 * @author tomsnail *

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

我想大多数Java初学者都会遇到的问题,那就是怎么配置环境,执行java -jar xxx.jar  都会报NoClassDefFindError,我在最开始学习的时候,也遇到了这些问题. 1.PATH path是路径的意思,我们直接在控制台运行一个程序时候,系统都会在指定的path下去找有没有这个程序,如果有就执行,没有就报错或者提示. 在windows系统中,使用echo %PATH%来查看PATH下的路径 在linux系统中,使用 echo $PATH 我们将java的bin目录加入pat

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

1.封装 import java.util.Date; public class Human { protected String name; protected BirthDay birthDay; protected String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return

重学JAVA基础(七):线程的wait、notify、notifyAll、sleep

/** * 测试thread的wait notify notifyAll sleep Interrupted * @author tomsnail * @date 2015年4月20日 下午3:20:44 */ public class Test1 { /** * 对象锁 * @author tomsnail * @date 2015年4月20日 下午3:14:13 */ private static final Object lockObject = new Object(); /** * 等

重学JAVA基础(四):线程的创建与执行

1.继承Thread public class TestThread extends Thread{ public void run(){ System.out.println(Thread.currentThread().getName()); } public static void main(String[] args) { Thread t = new TestThread(); t.start(); } } 2.实现Runnable public class TestRunnable