黑马程序员_Java基础加强5

本文深入探讨了Java动态代理技术,包括其目的、应用场景及其实现原理。介绍了如何使用Java反射API创建动态代理类,并提供了详细的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---------------------- 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));

	}

}


---------------------- Android、Java开发期待与您交流! ----------------------
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值