JDK动态代理(1)

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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
旅游社交小程序功能有管理员和用户。管理员有个人中心,用户管理,每日签到管理,景点推荐管理,景点分类管理,防疫查询管理,美食推荐管理,酒店推荐管理,周边推荐管理,分享圈管理,我的收藏管理,系统管理。用户可以在微信小程序上注册登录,进行每日签到,防疫查询,可以在分享圈里面进行分享自己想要分享的内容,查看和收藏景点以及美食的推荐等操作。因而具有一定的实用性。 本站后台采用Java的SSM框架进行后台管理开发,可以在浏览器上登录进行后台数据方面的管理,MySQL作为本地数据库,微信小程序用到了微信开发者工具,充分保证系统的稳定性。系统具有界面清晰、操作简单,功能齐全的特点,使得旅游社交小程序管理工作系统化、规范化。 管理员可以管理用户信息,可以对用户信息添加修改删除。管理员可以对景点推荐信息进行添加修改删除操作。管理员可以对分享圈信息进行添加,修改,删除操作。管理员可以对美食推荐信息进行添加,修改,删除操作。管理员可以对酒店推荐信息进行添加,修改,删除操作。管理员可以对周边推荐信息进行添加,修改,删除操作。 小程序用户是需要注册才可以进行登录的,登录后在首页可以查看相关信息,并且下面导航可以点击到其他功能模块。在小程序里点击我的,会出现关于我的界面,在这里可以修改个人信息,以及可以点击其他功能模块。用户想要把一些信息分享到分享圈的时候,可以点击新增,然后输入自己想要分享的信息就可以进行分享圈的操作。用户可以在景点推荐里面进行收藏和评论等操作。用户可以在美食推荐模块搜索和查看美食推荐的相关信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值