重学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

 

posted @ 2015-04-02 12:30  TomSnail  阅读(246)  评论(0编辑  收藏  举报