java反射机制和动态代理之动态代理(二)

说起代理,字面上的意思就是代替处理的意思,在java中代理就是一个对象代理另一个对象做着同样的事情,但是可以有更多的处理这件事情的其他功能,说起代理必不可少的就是反射机制,因为动态代理是在程序运行过程中才能够产生的类。动态代理运用的范围很多,比如spring的aop机制就是动态代理,其实动态代理也可以当做是拦截器,等等。

public interface Life {
    public void cook();
    public void isGood();
}
public interface Work {
    public void code();
    public int  time();
}
public class Man implements  Work,Life {

    @Override
    public void cook() {
        System.out.println("I am start cooking .....");
    }

    @Override
    public void  isGood() {
        System.out.println("my meal is good");
    }

    @Override
    public void code() {
        System.out.println("I am start coding.....");
    }

    @Override
    public int time() {
        System.out.println("I have coded 8h");
        return 8;
    }
}
public class MyHandler implements InvocationHandler {
    private Object target;//此处的是需要被代理的对象,这样被代理的对象就可以和处理器关联起来
    public MyHandler(Object target){
        this.target=target;
    }

    @Override
    public java.lang.Object invoke(java.lang.Object proxy, Method method, java.lang.Object[] args) throws Throwable {
        /*
        * 个人此处也可以当做一个拦截器或者过滤器,因为在调用方法之前可以根据target的属性判断此对象是否可以做相应的事情
        * */
        /*
        * 三个参数:
        * proxy:生成的那个代理对象,在使用的过程中几乎没有使用过着过这个对象,所以可以用来看看代理的信息
        * method:代理所调用的那个方法
        * args:方法的参数
        * */
        System.out.println("动态代理调用函数开始..................");
        Object obj=method.invoke(target,args);//方法中传入的是被代理的对象,这样在代理调用的时候其实就相当于被代理的对象在调用一样
        System.out.println("动态代理调用函数结束..................");
        return obj;
    }
}
@Test
public void test(){
    //需要被代理的对象
    Man man=new Man();
    //处理器Handler,这里处理器要与被代理的对象与之相关联,这样才能在代理对象调用的时候犹如被代理对象调用一样
    MyHandler myHandler=new MyHandler(man);
    /*
    * Proxy.newProxyInstance()中有三个参数
    * classLoader:类加载器,任意一个类的classLoader都可以,一般使用被代理的类的即可
    * interfaces:被代理对象的所有接口的数组,生成的代理对象会是这个数组里面的一个接口类型的代理对象
    * handler:处理的Handler,这个类必须要得提供Handler,被代理对象的处理过程就是在handler中做的
    * 返回值:返回值是Object,强行转为需要的接口类型
    * */
    Life life=(Life) Proxy.newProxyInstance(man.getClass().getClassLoader(),man.getClass().getInterfaces(),myHandler);
    life.cook();
    life.isGood();
    System.out.println(life.getClass());

    System.out.println("------------------------------------------------------------------------");

    Work work= (Work) Proxy.newProxyInstance(man.getClass().getClassLoader(),man.getClass().getInterfaces(),myHandler);
    work.code();
    int time=work.time();
    System.out.println(work.getClass());
}
动态代理调用函数开始..................
I am start cooking .....
动态代理调用函数结束..................
动态代理调用函数开始..................
my meal is good
动态代理调用函数结束..................
class com.sun.proxy.$Proxy4
------------------------------------------------------------------------
动态代理调用函数开始..................
I am start coding.....
动态代理调用函数结束..................
动态代理调用函数开始..................
I have coded 8h
动态代理调用函数结束..................

class com.sun.proxy.$Proxy4

从上面的结果看,在每一个函数被调用之前之后都加上了一句话。生成的对象是一个Proxy类型的而不是任意一种接口类型的,但是确实接口的子类,原因如下:在程序运行的过程中当运行到newProxyInstance的时候JVM会根据所提供的classLoader,interfaces,handler去动态的生成字节码文件,我们是看不导这个.class文件的,而生成的类的父类是Proxy,实现了interfaces数组的接口,但是怎么由代理对象调用方法的时候转向handler的invoke方法,本人暂时是不知道。

可以参考如下文章,这个个人觉得写的比较好:https://www.ibm.com/developerworks/cn/java/j-lo-proxy1/index.html(可能需要)

你可能感兴趣的:(java)