---------------------- Android、Java开发期待与您交流! ----------------------
Java代理
代理的目的:
为已存在的多个具有相同接口的目标类的各个方法增加一些系统功能:例如,异常处理、日志信息、计算方法的运行时间、事务管理等。
动态代理技术:
要为系统中的各种接口的类增加代理功能,那将需要太多的代理类,全部采用静态代理,那将是一种麻烦的事情
JVM可以在运行期间可以动态生成类的字节码,这种动态生成的类往往被用做代理类,即动态代理
CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,要为一个没有实现接口的类生成代理类,那么可以使用CGLIB库
代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标所返回的结果,还可以在代理方法的如下四个位置加上系统代码功能
1.在调用目标方法之前
2.在调用目标方法之后
3.在目标方法前后
4.在目标方法异常的catch块中
常用类的方法:
java.lang.reflect.InvocationHandler
此为代理实例的调用处理程序实现的接口
每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。
Object invoke(Object proxy,Method method,Object[] args):在代理实例上处理方法调用并放回结果
java.lang.reflect.Proxy
static Object newProxyInstance(ClassLoader loder,Class[] interfaces,InvocationHandler h):返回一个直接接口的代理类实例,该接口可以将方法调用指派到指定的调用处理其程序
static boolean isProxyClass(Class cl):当且仅当指定的类通过getProxyClass方法或newProxyInstance方法动态生成代理时放回true
static Class getProxyClass(ClassLoader loader,Class interfaces):返回代理类的java.lang.Class对象,并向其提供类加载器和接口数组
static InvocationHandler getInvocationHandler(Object proxy):返回指定代理实例的程序调用处理器
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;
public class ProxyTest extends Proxy {
private static final long serialVersionUID = 1L;
protected ProxyTest(InvocationHandler h) {
super(h);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public static void main(String[] args) throws Exception {
Class proxy = Proxy.getProxyClass(Collection.class.getClassLoader(),
Collection.class);
// getConstructor(proxy);
// getMethods(proxy);
Constructor constructor = proxy.getConstructor(InvocationHandler.class);
Collection proxy1, proxy2, proxy3;
// 创建代理对象形式一(匿名内部类方式)
proxy1 = (Collection) constructor
.newInstance(new MyInvocationHandler1());
System.out.println("proxy1.toString():" + proxy1.toString());
proxy1.clear();
// proxy1.size();
// 创建代理对象形式二
proxy2 = (Collection) constructor.newInstance(new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
final ArrayList target = new ArrayList();
//System.out.println("target.getClass():"+target.getClass());
//System.out.println("target.getClass().getInterfaces():"+target.getClass().getInterfaces());
proxy3 = (Collection) getProxy(target, new MyAdvice());
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
System.out.println("proxy3.size():" + proxy3.size());
System.out.println("proxy3.getClass().getName():"
+ proxy3.getClass().getName());
}
//获得代理实例
private static Object getProxy(final ArrayList target, final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
// long beginTime = System.currentTimeMillis();
advice.beforeMethod(method);
Object retValue = method.invoke(target, args);
// long endTime = System.currentTimeMillis();
advice.afterMethod(method);
// System.out.println(method.getName()+"方法run time of "+(endTime-beginTime));
return retValue;
}
});
return proxy3;
}
//打印代理对象的方法集合
public static void getMethods(Class proxy) {
Method[] methods = proxy.getMethods();
System.out.println("以下为成员方法:");
for (Method method : methods) {
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for (Class clazzParam : clazzParams) {
sBuilder.append(clazzParam.getName()).append(',');
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
}
//打印代理对象的构造方法集合
public static void getConstructor(Class proxy) {
Constructor[] constructors = proxy.getConstructors();
System.out.println("以下为构造方法:");
for (Constructor constructor : constructors) {
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes();
for (Class clazzParam : clazzParams) {
sBuilder.append(clazzParam.getName()).append(',');
}
if (clazzParams != null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length() - 1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
}
}
class MyInvocationHandler1 implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
import java.lang.reflect.Method;
/**
* 代理功能接口
* @author wxd
*
*/
public interface Advice {
public void beforeMethod(Method method);
public void afterMethod(Method method);
}
import java.lang.reflect.Method;
public class MyAdvice implements Advice {
long beginTime = 0;
@Override
public void beforeMethod(Method method) {
beginTime =System.currentTimeMillis();
System.out.println("beginTime:"+beginTime);
}
@Override
public void afterMethod(Method method) {
long endTime = System.currentTimeMillis();
System.out.println(method+"方法运行时长为:"+(endTime-beginTime));
}
}