java实现动态代理的两种方式 1.jdk动态代理方式,目标对象必须实现了接口,使用反射可生成目标对象的代理类$Proxy0,和目标对象实现了相同的接口; 2.cglib动态代理方式,目标对象没有实现接口,这时代理对象是目标对象的子类实例。

/**

  • 目标类实现的接口

*/ public interface PayService { void pay(); }

/**

  • 业务实现类

*/ public class PayServiceImpl implements PayService {

@Override
public void pay() {
	System.out.println("支付");
}

}

/**

  • jdk代理类调用接口中定义的业务方法时,实际调用的是该类的invoke方法

*/ public class PayServiceInvocationHandler implements InvocationHandler { private Object target;

public PayServiceInvocationHandler(Object target) {
	this.target = target;
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
	System.out.println("jdk动态代理 支付前......");
	Object result = method.invoke(target, args);
	System.out.println("jdk动态代理 支付后......");
	
	return result;
}

}

/**

  • jdk动态代理

*/ public class JdkProxy { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) throws Exception { // 代理类 com.sun.proxy.$Proxy0的class文件可以通过下面的配置选项输出到磁盘上 System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");

	/**
	 * 第一种生成代理对象的方法
	 * 1.生成InvocationHandler接口的实现类
	 * 2.获取InvocationHandler的构造方法
	 * 3.使用constructor生成代理对象
	 */
	PayService payService = new PayServiceImpl();
	Class proxyClazz = Proxy.getProxyClass(payService.getClass().getClassLoader(), payService.getClass().getInterfaces());
	Constructor constructor = proxyClazz.getConstructor(InvocationHandler.class);
	PayService payServiceProxy = (PayService) constructor.newInstance(new PayServiceInvocationHandler(payService));
	payServiceProxy.pay();
	
	/**
	 * 第二种生成代理对象的方法
	 * 使用Proxy.newProxyInstance()方法
	 * 本质上和上面的方法是一致的,只不过是封装成了一个方法,便于使用
	 */
	PayService payServiceProxy2 = (PayService) Proxy.newProxyInstance(payService.getClass().getClassLoader(), payService.getClass().getInterfaces(), new PayServiceInvocationHandler(payService));
	payServiceProxy2.pay();
	
}

}

生成的代理类$Proxy0可通过反编译查看源码,如下: public final class $Proxy0 extends Proxy implements PayService { private static Method m1; private static Method m3; private static Method m2; private static Method m0;

public $Proxy0(InvocationHandler paramInvocationHandler) {
	super(paramInvocationHandler);
}

public final boolean equals(Object paramObject) {
	try {
		return ((Boolean) this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
	} catch (Error | RuntimeException localError) {
		throw localError;
	} catch (Throwable localThrowable) {
		throw new UndeclaredThrowableException(localThrowable);
	}
}

/**
 * 接口中的方法 调用此方法,实际是调用InvocationHandler中的invoke()方法 可以在该方法中调用目标方法前后做一些处理,如记录日志等。
 */
public final void pay() {
	try {
		this.h.invoke(this, m3, null);
		return;
	} catch (Error | RuntimeException localError) {
		throw localError;
	} catch (Throwable localThrowable) {
		throw new UndeclaredThrowableException(localThrowable);
	}
}

public final String toString() {
	try {
		return (String) this.h.invoke(this, m2, null);
	} catch (Error | RuntimeException localError) {
		throw localError;
	} catch (Throwable localThrowable) {
		throw new UndeclaredThrowableException(localThrowable);
	}
}

public final int hashCode() {
	try {
		return ((Integer) this.h.invoke(this, m0, null)).intValue();
	} catch (Error | RuntimeException localError) {
		throw localError;
	} catch (Throwable localThrowable) {
		throw new UndeclaredThrowableException(localThrowable);
	}
}

static {
	try {
		m1 = Class.forName("java.lang.Object").getMethod("equals",
				new Class[] { Class.forName("java.lang.Object") });
		m3 = Class.forName("test.PayService").getMethod("pay", new Class[0]);
		m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
		m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
		return;
	} catch (NoSuchMethodException localNoSuchMethodException) {
		throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
	} catch (ClassNotFoundException localClassNotFoundException) {
		throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
	}
}

}

二、cglib动态代理

/**

  • 业务实现类

*/ public class PayServiceImpl { public void pay() { System.out.println("支付"); }

}

/**

  • cglib代理类的生成方式
  • 1.MethodInterceptor接口的实现类
  • 2.使用Enhancer生成目标对象的子类实例
  • @author Administrator

*/ public class PayServiceMethodInterceptor implements MethodInterceptor { public Object getInstance() { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(PayServiceImpl.class); enhancer.setCallback(this);

	Object proxyObj = enhancer.create();
	
	return proxyObj;
}

@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
	System.out.println("cglib动态代理 支付前");
	Object result = methodProxy.invokeSuper(obj, args);
	System.out.println("cglib动态代理 支付后");
	
	return result;
}

}

/**

  • cglib动态代理

*/ public class CglibProxy { public static void main(String[] args) { PayServiceMethodInterceptor payServiceMethodInterceptor = new PayServiceMethodInterceptor(); PayServiceImpl payServiceImpl = (PayServiceImpl) payServiceMethodInterceptor.getInstance(); payServiceImpl.pay(); } }

看精彩玄幻世界,尽在《大道扬帆》https://book.qidian.com/info/1012993779