动态代理

Posted 秋天de枫叶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理相关的知识,希望对你有一定的参考价值。

JDK方式:(实现缺陷,代理的对象必须要有对象接口)

 public static void main(String arg[]) 
        Istudent stu=new StudentImpl(); //创建一个对象
        stu= (Istudent) MyProxyFactory.getProxy(stu); //接收动态代理对象
        stu.myStudent();
        stu.myAddress();
    
//创建动态代理工厂
public class MyProxyFactory 
    /**
     * 创建一个代理对象
     * @param target
     * @return
     */
    public static Object getProxy(Object target)
        ManageProxy manager=new ManageProxy();  //创建一个manager对象
        manager.setManager(target); //将要代理的对象放入Manager对象中
        //创建动态代理对象
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),manager);
    
ManageProxy实现代理
public class ManageProxy implements InvocationHandler 
    private  Object target; //对一个私有的对象
    public void setManager(Object target)
        this.target=target; //接收传入的对象
    
    //代理方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        Util util=new Util(); //创一个工具类
        util.method1();//调用工具方法1
        //代理象传入的对象方法
        Object result=method.invoke(target,args);
        util.method2();//调用工具方法2
        return result;
    
Student接口
public interface Istudent 
    public void myStudent();
    public void myAddress();
Student实现类
public class StudentImpl implements Istudent 
    @Override
    public void myStudent() 
        System.out.println("小明是一个高中生");
    
    @Override
    public void myAddress() 
        System.out.println("小明住在学校宿舍");
    
Util类
public class Util 
    public void method1()
        System.out.println("调用方法开始!"+String.valueOf(System.currentTimeMillis()));
    
    public void method2()
        System.out.println("调用方法结束!"+String.valueOf(System.currentTimeMillis()));
    


CGLIB方式:(缺陷,要代理对象都必须重新创建一个对象实例)

主函数main:

  public static void main(String[] args) 
        CGLIBProxy cglibProxy = new CGLIBProxy();
        StudentImpl proxyImp = (StudentImpl)cglibProxy.getInstance(new StudentImpl());
        proxyImp.myStudent();
        proxyImp.myAddress();
    
CGLIBProxy 类实现MethodIntercetor接口
public class CGLIBProxy implements MethodInterceptor 
    private Object target;
    /**
     * 创建代理对象
     * @param target
     * @return
     */
    public Object getInstance(Object target) 
        this.target = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.target.getClass()); //创建一个子类
        // 回调方法
        enhancer.setCallback(this);
        // 创建代理对象
        return enhancer.create();
    
    @Override
    public Object intercept(Object obj, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable 
        Util util=new Util();
        util.method1();
        Object result = methodProxy.invokeSuper(obj, objects);
        util.method2();
        return result;
    

对比:

CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

--对比话语 摘自http://songbo-mail-126-com.iteye.com/blog/968792


































以上是关于动态代理的主要内容,如果未能解决你的问题,请参考以下文章

javascript基础01

javascript基础01

水槽系统日志代理没有选择消息并将其放入 HDFS

当我将电子邮件放入有效负载时,Angular 代理出错

IP代理软件怎么使用?

将vertx服务代理的代码放入docker