动态代理
要为已存在的多个具有相同接口的目标类的各个方法增加一个系统功能,例如日志,异常处理,计算方法运行时间等。
这个时候就需要创建一个代理类,这个类和目标类有相同的方法 ,只是在每个方法之前或者之后增加了一些特有代码。
在java中提供了一个类Proxy
Proxy:该类即为动态代理类,代理类和目标类要实现相同的接口,而且要有目标类相同的方法。
创建代理的方法:
例如:创建一个实现了Foo接口的代理类
方法一:
Class proxyclazz=Proxy.getProxyClass(Foo.class.getClassLoader,Foo.class);
Constructor constructor=proxyclazz.getConstructor(InvocationHandler hander);
Foo proxy1=(Foo)constructor.newInstance(new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
方法二:
Proxy proxy2=(Foo)Proxy.newProxyInstance(
Foo.class.getClassLoader,
Foo.class,
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
)
写一个ArrayList类的代理,实现和ArrayList中完全相同的功能,并可以计算每个方法运行的时间。
package com.itheima; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import com.itheima.proxy.Advice; import com.itheima.proxy.Myadvice; /* * * 4、 写一个ArrayList类的代理,实现和ArrayList中完全相同的功能,并可以计算每个方法运行的时间。 */ public class Text4 { public static void main(String[] args) { final ArrayList traget=new ArrayList(); Collection proxy = (Collection)getProxy(traget,new Myadvice()); proxy.add("asdf"); proxy.add("sadf"); proxy.add("asdfasdfasdf"); } public static Object getProxy(final Object traget,final Advice advice) { Object proxy=Proxy.newProxyInstance( traget.getClass().getClassLoader(), traget.getClass().getInterfaces(), new InvocationHandler(){ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.beforeMethod(method); Object val=method.invoke(traget, args); advice.afterMethod(method); return val; } }); return proxy; } }
package com.itheima.proxy; import java.lang.reflect.Method; public interface Advice { void beforeMethod(Method method); void afterMethod(Method method); }
package com.itheima.proxy; import java.lang.reflect.Method; public class Myadvice implements Advice { long begintime=0; @Override public void beforeMethod(Method method) { begintime=System.currentTimeMillis(); } @Override public void afterMethod(Method method) { long endtime=System.currentTimeMillis(); System.out.println(method.getName()+"\t"+"run time is:"+(endtime-begintime)); } }
浙公网安备 33010602011771号