首页 > 代码库 > java动态代理

java动态代理

  一直对动态代理很陌生,总以为是很高深的东西,就像java的反射一样,然而真正去实现之后,也就那么回事,怕自己遗忘,故整理一下思绪,记录在此。

package com.zhj;public  interface Cat {//    建立Cat接口,之前我好奇,把接口换成抽象类后,取代理对象的时候//    出现ClassCastException.     void eat(int num);     void sleep(int hour);}
 

 实现类:

package com.zhj;public class LazyCat implements Cat {    public void eat(int num) {        System.out.println("I eat "+num+" fishes every day");    }    public void sleep(int hour) {        System.out.println("I sleep "+hour+" hours every day");    }}

插入日志的接口和实现类:

package com.zhj;public interface LogUtil {    public void beforeMethod();    public void testLazyCat(int sum);}
package com.zhj;public class LogUtilImp implements LogUtil {    @Override    public void beforeMethod() {        System.out.println("method begin");        System.out.println("---------------");    }    @Override    public void testLazyCat(int num) {        System.out.println("---------------");        if(num>8){            System.out.println("It is a lazy cat!");        }        else{            System.out.println("It is a good cat!");                    }    }}

接下来是重头戏了:实现InvocationHandle接口,就只有一个invoke方法,内部利用反射完成对方法的调用。

package com.zhj;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {    // prepare the target to  proxy,用于注入被代理对象    private Object target;    public void setTarget(Object target){        this.target=target;    }    @Override    public Object invoke(Object proxy, Method method, Object[] args)            throws Throwable {        LogUtil lu=new LogUtilImp();        //在方法前调用日志        lu.beforeMethod();        //java反射,target为被代理对象,args是方法传入的参数数组对象        Object result=method.invoke(target, args);                //方法后调用日志类方法,并且还能传递传入方法的参数        lu.testLazyCat((Integer)args[0]);                return result;    }}
package com.zhj;import java.lang.reflect.Proxy;public class MyProxy {    public static Object getProxy(Object target){    //实例化自定义handler    MyInvocationHandler handler=new MyInvocationHandler();    //注入被代理对象    handler.setTarget(target);    //生成代理对象    return Proxy.newProxyInstance(target.getClass().getClassLoader()            , target.getClass().getInterfaces(), handler);    }}

Test:

package com.zhj;public class Test {    public static void main(String[] args){        //new 一个lazyCat        Cat target=new LazyCat();        //拿到代理“懒猫”,此懒猫已非彼懒猫,每调用一个方法,方法前后都被加了日志        Cat cat=(Cat) MyProxy.getProxy(target);                cat.sleep(12);            }}

 

java动态代理