《Java设计模式》之代理模式 -Java动态代理(InvocationHandler) -简单实现

Java代理模式及相关类测试
本文介绍了代理模式,它是对象的结构模式,可细分为远程、虚拟、缓冲、保护代理等。还给出了借鉴文章链接,同时阐述了Java动态代理相关内容,包括AbstractUserDAO抽象类、UserDAO类、DAOLogHandler处理程序、Client测试类及测试输出。
如题
  • 代理模式是对象的结构模式。代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。
  • 代理模式类图
  • 代理模式可细分为如下, 本文不做多余解释
  • 远程代理
  • 虚拟代理
  • 缓冲代理
  • 保护代理
借鉴文章

https://www.cnblogs.com/java-my-life/archive/2012/04/23/2466712.html
《Java设计模式》 -Java动态代理(InvocationHandler)

AbstractUserDAO 抽象的用户DAO类, 抽象主题角色
package proxy;

/**
 * @description  抽象的用户DAO类, 抽象主题角色
 * @Date 2019/6/22 10:05
 */
public interface AbstractUserDAO {
     Boolean findUserById(Long userId);
}
UserDAO 用户DAO类,具体主题角色
package proxy;

/**
 * @description 类的详细说明: 用户DAO类,具体主题角色
 * @Date 2019/6/22 10:08
 */
public class UserDAO implements AbstractUserDAO{
    /**
     * 简单举个栗子,实际应用时自行调整
     * @param userId
     * @return
     */
    @Override
    public Boolean findUserById(Long userId) {
        Long maxx =new Long( "10000000");
        if(userId>=1 && userId<=maxx){
            System.out.println("查询ID为 "+userId+" 的用户信息成功!");
            return true;
        }else{
            System.out.println("查询ID为 "+userId+" 的用户信息失败");
            return false;
        }

    }
}
DAOLogHandler 自定义请求处理程序, 前后打印日志
package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Calendar;
import java.util.GregorianCalendar;

/**
 * @description  自定义请求处理程序,实现前置和后置通知, 及前后打印日志
 * @Date 2019/6/22 10:15
 */
public class DAOLogHandler implements InvocationHandler {
    /**calendar 属性用于打印时间*/
    private Calendar calendar;
    private Object object;

    /**
     * 自定义有参构造器,用以注入一个需要提供代理的真实主题对象
     * @param object 代理对象
     */
    public DAOLogHandler(Object object) {
        this.object = object;
    }

    /**
     * @param proxy 需要代理的类
     * @param method 需要代理的方法
     * @param args 代理方法的参数数组
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        beforeInvoke();
        /**转发调用*/
        Object result = method.invoke(object,args);
        afterInvoke();
        return result;
    }
    /**
     * 实现前置通知处理
     */
    private void beforeInvoke(){
        //使用当前时间构造默认的<code>GregorianCalendar类</code> ,在默认时区, 使用默认值
        calendar = new GregorianCalendar();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        System.out.println("------------调用时间 "+hour+":"+minute+":"+second+"------------");
    }
    /**
     * 实现后置通知处理
     */
    private void afterInvoke(){
        calendar = new GregorianCalendar();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        int minute = calendar.get(Calendar.MINUTE);
        int second = calendar.get(Calendar.SECOND);
        System.out.println("------------调用方法结束 "+hour+":"+minute+":"+second+"------------\n");
    }
}
Client 主要测试类
package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

/**
 * 客户端类, 主要测试类
 *
 * 题目描述: 某公司要为公司的OA(办公自动化)系统的数据访问层DAO增加方法调用日志,
 *          记录每一个方法被调用的时间和调用结果,现使用动态代理(InvocationHandler)进行设计和实现.
 */
public class Client {
    public static void main(String[] args) {
        InvocationHandler handler = null;

        AbstractUserDAO userDAO = new UserDAO();
        /**初始化调用处理器*/
        handler = new DAOLogHandler(userDAO);

        AbstractUserDAO proxy=null;

        //动态创建代理对象
        // Proxy.newProxyInstance : 返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。
        proxy = (AbstractUserDAO) Proxy.newProxyInstance(AbstractUserDAO.class.getClassLoader(),
                new Class[]{AbstractUserDAO.class},handler);
        proxy.findUserById((long)001);
        proxy.findUserById((long)999999999);
    }
}
测试输出

------------调用时间 10:59:25------------
查询ID为 1 的用户信息成功!
------------调用方法结束 10:59:25------------

------------调用时间 10:59:25------------
查询ID为 999999999 的用户信息失败
------------调用方法结束 10:59:25------------

转载于:https://www.cnblogs.com/zhazhaacmer/p/11068254.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值