再学JAVA基礎(三):動的代理

8532 ワード

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にはこの制限はありません.
それから性能、私は1篇のネット上ですでに対比があることを見て、jdk 7/8でcglibと比較して、かえってjdkの性能はとても良くて、見てhttp://www.cnblogs.com/haiq/p/4304615.html