JDK动态代理分析(1)
java.lang.Object
|_java.lang.reflect.Proxy
Proxy类继承了Object实现了Serializable接口
有一个构造方法,
JDK API中的描述:
使用其调用处理程序的指定值从子类(通常为动态代理类)构建新的Proxy实例
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
java.lang.reflect
接口InvocationHandler
JDK API中的描述:
InvocationHandler是代理实例的调用处理程序实现的接口.
每个代理实例都具有一个关联的调用处理程序.对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的invoke方法.
里面有一个方法invoke
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
JDK API中的描述:
在代理实例上处理方法调用并返回结果.
参数说明:Object proxy:在其上调用方法的实例
Method method:对应于在代理实例上调用接口方法的Method实例,Method对象的声明类将是在其中声明方法的接口,该接口可以是代理类赖以继承方法的代理接口的超接口.
args:包含传入代理实力上方法调用的参数值的对象数组,如果接口方法不使用参数,则为null,基本类型的参数被包装在适当基本包装容器类(如java.lang.Integer或java.lang.Boolean)的实例中.
首先得创建一个代理类出来,然后由代理类对象去调用被代理类需要被调用的方法.
于是在Proxy中有这个方法
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
{
...
}
JDK API对newProxyInstance(…)这个方法的描述:
返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序.
ClassLoader loader- 定义代理类的类加载器
Class<?>[] interfaces- 代理类要实现的接口列表
InvocationHandler h- 指派方法调用的调用处理程序
JDK动态代理实例
定义一个目标类(被代理的类)
public class TargetClass{
/**
* @Title: add
* @author: KevinZeng
* @date: 2020年1月5日 下午6:42:06
* @Description: 具体被代理的add()方法
* @return: void
*/
public void add() {
System.out.println("具体被代理的add()方法");
}
}
因为JDK动态代理Proxy类中
- 准备参数2 Class<?>[] interfaces
newInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)方法需要接口参数列表,这个参数列表就是代理类要实现的接口列表,于是将被代理类向上抽取出一个接口.
/**
* @ClassName: TargetClassInterface
* @Description: 代理类要实现的接口之一,被代理类实现的接口
* @author: KevinZeng
* @date: 2020年1月5日 下午7:17:53
*/
public interface TargetClassInterface {
public void add();
}
改写被代理类TargetClass,被代理类实现TargetClassInterface
/**
* @ClassName: TargetClass
* @Description: 被代理的类
* @author: KevinZeng
* @date: 2020年1月5日 下午6:40:55
*/
public class TargetClass implements TargetClassInterface{
/**
* @Title: add
* @author: KevinZeng
* @date: 2020年1月5日 下午6:42:06
* @Description: 具体被代理的add()方法
* @return: void
*/
public void add() {
System.out.println("具体被代理的add()方法");
}
}
- newInstance()准备参数3 InvocationHandler h
于是定义一个Handler类作为代理的处理器,实现InvocationHandler接口,重写invoke方法.
因为invoke方法想要被执行,必须传进来一个被代理类的对象,于是通过构造方法构建一个targetObejct作为被代理的目标,这个目标参数于是就作为了invoke()方法的参数.
处理器需要有一个目标,Object targetObject;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* @ClassName: ProxyHandler
* @Description: 代理的处理器
* @author: KevinZeng
* @date: 2020年1月5日 下午7:26:54
*/
public class ProxyHandler implements InvocationHandler{
//被代理的目标
Object targetObejct;
public ProxyHandler(Object obj){
this.targetObejct = obj;
}
/**
参数1:代理类对象
参数2:被代理的方法
参数3:方法参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行目标方法
Object rs = method.invoke(targetObejct,args);
return rs;
}
}
定义一个事务管理器
public class TranctionMannage{
public static void beginTranscation(){
System.out.println("开启事务");
}
public static void commitTranscation(){
System.out.println("提交事务");
}
public static void rollBackTranscation(){
System.out.println("回滚事务");
}
}
可以在invoke方法内在执行目标方法前后进行增强事务的操作.修改如下;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//开启事务
TranctionMannage.beginTranscation();
Object rs = null;
try{
//执行目标方法
rs = method.invoke(targetObejct,args);
}catch(Exception e){
//回滚事务
TranctionMannage.rollBackTranscation();
}
//提交事务
TranctionMannage.commitTranscation();
return rs;
}
编写测试类
public class Test {
public static void main(String[] args) {
// 1.创建一个被代理类的对象
TargetClassInterface targetClass = new TargetClass();
// 2.创建代理处理器
ProxyHandler proxyHandler = new ProxyHandler(targetClass);
// 3.获取代理
Class<?>[] interfaces = { TargetClassInterface.class };
TargetClassInterface targetClassInterface = (TargetClassInterface) Proxy.newProxyInstance(Test.class.getClassLoader(), interfaces, proxyHandler);
targetClassInterface.add();
}
}
下面是程序生成的代理类
package com.sun.proxy;
import com.zw.dy.TargetClassInterface;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.lang.reflect.UndeclaredThrowableException;
//自动帮程序生成的代理类 : 继承 Proxy 实现 TargetClassInterface
public final class $Proxy0 extends Proxy implements TargetClassInterface
{
private static Method m0; // hashCode
private static Method m1; // equals
private static Method m2; // toString
private static Method m3; //TargetClassInterface add 只有方法声明
static
{
try
{
m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
m3 = Class.forName("com.zw.dy.TargetClassInterface").getMethod("add", new Class[0]);
return;
}
catch (NoSuchMethodException localNoSuchMethodException)
{
throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
}
catch (ClassNotFoundException localClassNotFoundException)
{
throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
}
}
// 代理类的构造方法 :InvocationHandler : ProxyHandler
public $Proxy0(InvocationHandler paramInvocationHandler)
throws
{
//Proxy(ProxyHandler) //创建 proxy 对象 ---> this.h = ProxyHandler;// proxy 类 的 InvocationHandler 属性 : proxyHandler
super(paramInvocationHandler);
}
public final boolean equals(Object paramObject)
throws
{
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);
}
}
public final String toString()
throws
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final void add()
throws
{
try
{
// this.h ===> super.h : proxy h 属性 : proxyHandler proxy0 : 生成的代理类对象 m3 被代理的方法 add null 传进来的参数 targetObject : TargetClass
this.h.invoke(this, m3, null); // proxyHandler .invoke(proxy0) :// TranctionMannage.beiginTranscation(); rs = add.invoke(targetObject, args); TranctionMannage.commitTranscation();
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final int hashCode()
throws
{
try
{
return ((Integer)this.h.invoke(this, m0, null)).intValue();
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
}