1动态代理
代理模式是给一个对象提供一个代理,以控制对它的访问,如只有授权用户才可以访问某个对象,给对象添加日志功能。
动态代理是提供运行时实现代理模式的一种方法。
2 动态代理结构图
如上图所示,当要用到代理对象时,需调用代理产生器创建一个代理类来控制被代理的对象。
代理产生器的功能在JDK中也就是通过Proxy.newProxyInstance来动态创建一个代理类。
3 动态代理在Java中的实现
假设有一个CarCompany接口,他具备制造汽车的功能makeCar();不同的厂商有不同的makeCar的实现。现在通过动态代理来添加一个测试makeCar所消耗时间的功能。
1. CarCompany.java
Interface CarCompay{
Public void makeCar();
}
2. CarCompanyA.java
public class CarCompanyA implements CarCompany {
public void makeCar() {
System.out.println("Company A make a car!");
}
}
3. CarCompanyHandler.java
Public class CarCompany implements CarCompany{
CarCompany com;
public CarCompanyHandler(CarCompany a){
this.com = a;
}
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("makeCar")){
System.out.println("time1:" + System.currentTimeMillis());
method.invoke(this.com,new Class[]{});
System.out.println("time2:" + System.currentTimeMillis());
}
return null;
}
}
4. Test.java
Public class Test{
Public static void main(String[] arg){
CarCompanyA a = new CarCompanyA();
CarCompanyHandler handler = new CarCompanyHandler(a);
//产生一个新的代理类
CarCompany com = (CarCompany) Proxy.newProxyInstance(Test.class
.getClassLoader(), new Class[] { CarCompany.class }, handler);
com.makeCar();
}
}
5. 代理产生器动态生成的类(Proxy.newProxyInstance产生的)
相信看了如下代码后就会很清楚动态代理的执行过程。
public final class XXXXX$proxy extends Proxy
implements CarCompany
{
public final void makeCar()
{
try
{
//调用InvocationHandler的invoke方法
super.h.invoke(this, m3, null);
return;
}
catch(Error _ex) { }
catch(Throwable throwable)
{
throw new UndeclaredThrowableException(throwable);
}
}
private static Method m3;
static
{
try
{
m3 = Class.forName("com.home.CarCompany").getMethod("makeCar", new Class[0]);
}
catch(NoSuchMethodException nosuchmethodexception)
{
throw new NoSuchMethodError(nosuchmethodexception.getMessage());
}
catch(ClassNotFoundException classnotfoundexception)
{
throw new NoClassDefFoundError(classnotfoundexception.getMessage());
}
}
public a$proxy(InvocationHandler invocationhandler)
{
super(invocationhandler);
}
}