java动态代理

    前几天面试,被问到java动态代理,当时支支吾吾回答了,用到了字节码生成技术,proxy,Method类。动态代理用到了反射,在面试中经常被问到,自己也有断断续续学习,这方面的知识。但是一直都不是太明白。看了一些博客后,现在将自己的理解整理如下:

    首先写了一个car接口类,里面只有一个接口run

     

package proxy;

public interface Car{
   public void run();
}

  接着写一个car接口的实现类,

package proxy;

public class BMWCar implements Car {

    @Override
    public void run() {
         System.out.println("BMW car is running!");
    }

}

然后是编写Invoke类,我认为这个类并不是必须的,即没有这个类,一样可以实现动态代理,即在代理类中直接通过obj.run()一样可以实现动态代理。但是由于,java中的代理是动态的,是自动生成的,我们无法直接在动态代理类 加入新的功能。

    所以,只能通过反射技术,间接调用被代理对象中的方法。

   

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class Invoke implements InvocationHandler {
    public Object obj;
    public Invoke(Object obj) {
      this.obj=obj;        
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("进入了invoke方法");
        Object re=method.invoke(obj, args);
        System.out.println("结束了invoke方法");
        return re;
    }

}

然后加入main类,测试我们的动态代理是否成功。


package proxy;


import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


public class Main {
public static void main(String[] args) {
Car car=new BMWCar();
Invoke in=new Invoke(car);
Method me=null;
try {
Car carProxy=(Car)Proxy.newProxyInstance(car.getClass().getClassLoader(), car.getClass().getInterfaces(), in);
carProxy.run();
} catch (Throwable e) {
e.printStackTrace();
}
}
}

     看了其他资料后,我发现java动态代理会生成一个$proxy.class的代理类,我没有找到这个类,难不成它不放在磁盘文件中?

现在我推测$proxy.class类的代码是这样的:

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class $Proxy extends Proxy implements Car {
	//Proxy类中有protected修饰的invokeHandler对象,当前类可以使用
	private static Method m1=null;
	static {
		try{
			m1=Class.forName("proxy.Car").getMethod("run", new Class[0]);
		} catch (NoSuchMethodException | SecurityException | ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	protected $Proxy(InvocationHandler h) {
		super(h);
	}
	@Override
	public void run() {
		try {
			 super.h.invoke(this, m1, null);
		} catch (ClassNotFoundException e1) {
			e1.printStackTrace();
		} catch (Throwable e) {
			e.printStackTrace();
		}	
	}
   
}

  

posted @ 2017-09-07 13:04  cheerupWoo  阅读(134)  评论(0编辑  收藏  举报