1.什么是动态代理?
答:动态代理可以提供对另一个对象的访问,同时隐藏实际对象的具体事实。代理一般会实现它所表示的实际对象的接口。代理可以访问实际对象,但是延迟实现实际对象的部分功能,实际对象实现系统的实际功能,代理对象对客户隐藏了实际对象。客户不知道它是与代理打交道还是与实际对象打交道。
2.为什么使用动态代理?
答:因为动态代理可以对请求进行任何处理
3.使用它有哪些好处?
答:因为动态代理可以对请求进行任何处理
4.哪些地方需要动态代理?
答:不允许直接访问某些类;对访问要做特殊处理等
目前Java开发包中包含了对动态代理的支持,但是其实现只支持对接口的的实现。 其实现主要通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口。
Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现
以下为模拟案例,通过动态代理实现在方法调用前后向控制台输出两句字符串
目录结构:
实例代码:
5、接口
package com.ren.day03;
import java.lang.reflect.Method;
//代理类接口
public interface Advice {
void beforeMehtod(Method method);
void afterMehtod(Method method);
}
6、实现了该接口的类
package com.ren.day03;
import java.lang.reflect.Method;
public class MyAdvice implements Advice {
private long start = 0;
private long end = 0;
@Override
public void beforeMehtod(Method method) {
// TODO Auto-generated method stub
System.out.println("方法调用前");
start = System.currentTimeMillis();
}
@Override
public void afterMehtod(Method method) {
// TODO Auto-generated method stub
end = System.currentTimeMillis();
System.out.println(method.getName() + "run time :" + (end - start));
System.out.println("方法调用后");
}
}
7、测试类
package com.ren.day03;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest {
/**
* @param args
* @throws NoSuchMethodException
* @throws SecurityException
* @throws InvocationTargetException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws IllegalArgumentException
*/
public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
// TODO Auto-generated method stub
Class clazzProxy = Proxy.getProxyClass(
Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy.getName());
System.out.println("---------Begin constructor list---------");
Constructor[] constructors = clazzProxy.getConstructors();
for (Constructor constructor : constructors) {
String name = constructor.getName();
StringBuilder sb = new StringBuilder(name);
sb.append("(");
Class[] clazzParaType = constructor.getParameterTypes();
for (Class clazzPara : clazzParaType) {
sb.append(clazzPara.getName());
sb.append(",");
}
if (clazzParaType.length != 0)
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
System.out.println(sb.toString());
}
System.out.println("---------Begin method list---------");
Method[] methods = clazzProxy.getMethods();
for (Method method : methods) {
String name = method.getName();
StringBuilder sb = new StringBuilder(name);
sb.append("(");
Class[] clazzParaType = method.getParameterTypes();
for (Class clazzPara : clazzParaType) {
sb.append(clazzPara.getName());
sb.append(",");
}
if (clazzParaType.length != 0)
sb.deleteCharAt(sb.length() - 1);
sb.append(")");
System.out.println(sb.toString());
}
System.out.println("-----------Create instance object--------------");
// clazzProxy.newInstance();
//得到构造器
Constructor constructor = clazzProxy.getConstructor(InvocationHandler.class);
//实现InvocationHandler接口
class MyInvocationHandler implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
//创建实例对象1
Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHandler());
//调用方法
System.out.println(proxy1);
System.out.println(proxy1.toString());
//从toString方法可以看出创建实例对象成功,至于打印为什么是null,是因为toString方法返回null
//创建实例对象2,用内部类实现InvocationHandler接口
Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
});
//创建实例对象3,直接用Rroxy,newProxyInstance方法
/*Collection proxy3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler() {
ArrayList target = new ArrayList();
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
System.out.println("方法调用前");
long start = System.currentTimeMillis();
Object obj = method.invoke(target, args);
long end = System.currentTimeMillis();
System.out.println(method.getName() + "run time :" + (end - start));
System.out.println("方法调用后");
return obj;
}
});*/
final ArrayList target = new ArrayList();
Collection proxy3 = getProxy(target,new MyAdvice());
//再次调用方法
proxy3.add("fff");
proxy3.add("fff");
proxy3.add("fff");
System.out.println(proxy3.size());
}
//创建实例对象3,直接用Rroxy,newProxyInstance方法
public static Collection getProxy(final ArrayList target,final Advice advice) {
Collection proxy3 = (Collection)Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
advice.beforeMehtod(method); //通过对象传入方法
Object obj = method.invoke(target, args);
advice.afterMehtod(method);
return obj;
}
});
return proxy3;
}
}