动态代理3之代理工厂实现

动态代理的深化:承接动态代理2( 对 上级实例进行 深化),也就是 spring 的前身

(必须掌握)实例:

文件说明:1.有一个Waiter接口,该接口有一个 server() 、ShouQian()方法

2.有一个 Waiter接口的实现类,ManWaiter类

3.一个 测试Test类

     4. 后置增强接口: AfterAdvice 接口

     5.前置增强接口:BeforeAdvice接口

     6. 生成代理对象 的 ProxyFactory类

1. Waiter.java 接口

// 服务员

public interface Waiter {

    // 服务

    public void serve();

    

    //收钱

    public void shouQian();

}

 

2. BeforeAdvice.java 接口,前置增强接口

/**

* 前置增强

* @author cxf

*

*/

public interface BeforeAdvice {

    public void before();

}

 

3. AfterAdvice.java 接口,后置增强接口

/**

* @function 后置增强

* @author not-bug

*

*/

public interface AfterAdvice {

    public void after();

}

 

4 . ManWaiter.java 类,该类实现了 Waiter接口

//该类实现了 Waiter 接口

public class ManWaiter implements Waiter {

    public void serve() {

        System.out.println("服务中...");

    }

    

    public void shouQian() {

        System.out.println("混蛋,给我钱!");

    }

}

 

5. ProxyFactory.java 类,用来生成代理对象的类

/**

* 它用来生成代理对象

* 它需要所有的参数

* * 目标对象

* * 增强

* @author cxf

*/

/**

* 1. 创建代理工厂

* 2. 给工厂设置三样东西:

* * 目标对象:setTargetObject(xxx);

* * 前置增强:setBeforeAdvice(该接口的实现)

* * 后置增强:setAfterAdvice(该接口的实现)

* 3. 调用createProxy()得到代理对象

* * 执行代理对象方法时:

* > 执行BeforeAdvicebefore()

* > 目标对象的目标方法

* > 执行AfterAdviceafter()

* @author cxf

*

*/

public class ProxyFactory {

    private Object targetObject;//目标对象

    private BeforeAdvice beforeAdvice;//前置增强

    private AfterAdvice afterAdvice;//后置增强

      

    

    /**

     * 用来生成代理对象

     * @return

     */

    public Object createProxy() {

        /*

         * 1. 给出三大参数

         */

        ClassLoader loader = this.getClass().getClassLoader();

        Class[] interfaces = targetObject.getClass().getInterfaces();

        InvocationHandler h = new InvocationHandler() {

            public Object invoke(Object proxy, Method method, Object[] args)

                    throws Throwable {

                /*

                 * 在调用代理对象的方法时会执行这里的内容

                 */

                // 执行前置增强

                if(beforeAdvice != null) {

                    beforeAdvice.before();

                }

                

                Object result = method.invoke(targetObject, args);//执行目标对象的目标方法

                // 执行后置增强

                if(afterAdvice != null) {

                    afterAdvice.after();

                }

                

                // 返回目标对象的返回值

                return result;

            }

        };

        /*

         * 2. 得到代理对象

         */

        Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);

        return proxyObject;

    }

      

    

    public Object getTargetObject() {

        return targetObject;

    }

    public void setTargetObject(Object targetObject) {

        this.targetObject = targetObject;

    }

    public BeforeAdvice getBeforeAdvice() {

        return beforeAdvice;

    }

    public void setBeforeAdvice(BeforeAdvice beforeAdvice) {

        this.beforeAdvice = beforeAdvice;

    }

    public AfterAdvice getAfterAdvice() {

        return afterAdvice;

    }

    public void setAfterAdvice(AfterAdvice afterAdvice) {

        this.afterAdvice = afterAdvice;

    }

}

 

6. Test.java ,测试类

 

/*

* 目标是让目标对象和增强都可以切换!

*/

public class Demo3 {

    @Test

    public void fun1() {

        ProxyFactory factory = new ProxyFactory();//创建工厂

        factory.setTargetObject(new ManWaiter());//设置目标对象

        factory.setBeforeAdvice(new BeforeAdvice() {//设置前置增强

            public void before() {

                System.out.println("您好不好!");

            }

        });

        

        factory.setAfterAdvice(new AfterAdvice() {//设置后置增强

            public void after() {

                System.out.println("再见不见!");

            }

        });

        

        Waiter waiter = (Waiter)factory.createProxy();

        //waiter.shouQian();

        waiter.serve();

    }

    

    //转账方法

    public void zhuanZhang() {

        /*

         * 1.

         * 2.

         * 3.

         */

    }

}

 

运行结果:

转载于:https://www.cnblogs.com/Prozhu/p/5452962.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255418.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【bug修复】解决ValueError: Tensor(“Variable:0“ dtype=float32_ref) must be from the same graph as Tensor(“R

bug:描述 在进行tensorflow进行搭建CNN网络时,在定义CNN的py文件中调用cnn模型,运行正常,但是在其他py文件中进行时就出现问题 ValueError: Tensor(“Variable:0” dtypefloat32_ref) must be from the same graph as Tensor(“Reshape:0”,…

Linux 图片传输功能c/c++(初版)

由于深度学习任务的需要,要在程序里面嵌入一个module。 这个module 的功能是接收来自ios客户端的图片。并且传送给深度学习分类器进行处理。 于是看了看各种各样的 module 实现方案。 先是用IO函数把图片以数组的方式存起来。 再和服务器建立连接,socket…

Val编程-val系列编程思想

利用Val语言可以编写出各种各样的应用程序。正如windows phone面临的窘境一样,受众太小,市场不大。应用程序不多,所以也谈不上成熟。国内的应用程序基本上就是简单的小程序,谈不上什么编程思想。国外许多都是基于kernel的而衍生出…

【pyqt5学习】——bug修复,利用qt资源库qrc文件进行背景图像设置,不显示图像

目录 bug描述 bug分析 bug解决 bug描述 利用下面文章的方法进行资源设置后,有的显示了有的没有显示 【pyqt5学习】——pyqt5中.qrc资源文件的创建与编写_有情怀的机械男的博客-CSDN博客_python qrc目录一、说明二、安装pyqt5以及相关工具(pyqt5、pyuic…

Datalore:用于机器学习可视化的新Web方案!

前不久,JetBrains团队发布了Datalore,这是一款基于云的web应用程序,用于构建机器学习模型并在Python中创建丰富的可视化。最新的测试版本旨在简化构建机器学习模型的流程,并帮助开发人员进行数据分析。由于Datalore的智能编码辅助…

CSS魔法堂:重拾Border之——图片作边框

前言 当CSS3推出border-radius属性时我们是那么欣喜若狂啊,一想到终于不用再添加额外元素来模拟圆角了,但发现border-radius还分水平半径和垂直半径,然后又发现border-top-left/right-radius的水平半径之和大于元素宽度时,实际值会…

共享内存简介和mmap 函数

一、共享内存简介 共享内存区是最快的IPC形式,这些进程间数据传递不再涉及到内核,换句话说是进程不再通过执行进入内核的系统调用来传递彼此的数据。 即每个进程地址空间都有一个共享存储器的映射区,当这块区域都映射到相同的真正的物理地址空…

【pyqt5学习】——QToolTip,QLabel控件,伙伴关系

目录 0、学习资源 1、给控件设置提示信息——QToolTip 2、QLabel控件(显示图像、设置超链接、信号绑定) 3、QLabel伙伴关系 1)代码 2)效果 3)知识点addWidget 0、学习资源 PyQt5教程,来自网易云课堂…

SylixOS中select原理及使用分析

2019独角兽企业重金招聘Python工程师标准>>> 1. select接口简介 1.1 select接口使用用例 select是操作系统多路I/O复用技术实现的方式之一。 多路I/O复用技术大致使用场景为:构造一张感兴趣的文件描述符列表,然后调用多路复用的IO接口&#x…

【pyqt5学习】——QLineEdit学习(回显模式)

目录 1、回显模式 2、成果显示 3、知识点 1)FormLayout布局添加addRow方法 2)在输入框显示灰色提示字体,输入内容时消失setPlaceholderText 3)设置回显模式setEchoMode 4、完整代码 1、回显模式 QLineEdit控件的主要功能是输…

【pyqt5学习】——QLineEdit控件输入校验器Validator、掩码setInputMask限制输入、textChanged信号

目录 1、输入校验器——限制输入框输入的内容 1)校验器类型——整数、浮点数、数字字母结合(正则) 2)步骤 3)结果 ​编辑 ​编辑 4)完整代码 2、利用掩码进行输入的限制 0)掩码对照表 1…

PyOpenCL图像处理:Box模糊

为什么80%的码农都做不了架构师?>>> # -*- coding: utf-8 -*-from __future__ import absolute_import, print_function import numpy as np import pyopencl as cl import cv2 from PIL import Imagedef RoundUp(groupSize, globalSize): r globalSi…

MySQL日志分类及性能分析你应该知道的知识

为什么80%的码农都做不了架构师?>>> MySQL日志记录了MySQL数据库日常操作和错误信息,MySQL总共有四种类型的日志,通过分析这些日志可以查询到MySQL的运行情况、用户操作、错误信息等,可以为MySQL的管理和优化提供必要…

android基础组件----Button的使用

按钮由文本或图标(或文本和一个图标)组成,当用户触摸到它时,会发生一些动作。今天我们开始Button的学习。少年的爱情永远不够用,一杯酒足以了却一件心事。 Button的简要说明 根据你是否想要一个带有文本的按钮&#xf…

【pyqt5学习】——QTextEdit控件学习:获取文本、添加文本

目录 1、QTextEdit控件介绍 2、QTextEdit控件添加文本、添加HTML格式 3、QTextEdit控件获取文本、获取HTML格式文本 4、案例 1)完整代码 2)效果 1、QTextEdit控件介绍 QTextEdit控件是一个支持多行输入的输入框,支持HTML进行格式的设置 2…

空间变化

空间变化 第一种:圆 第二种: 矩形 第三种:正五边形 第四种:正六边形 第五种:腰圆 算法: 在规则图形(不包括圆心-直径法)中,等于或者超过三个点。一般的,利用p1,p2,p3来建立一个用户…

【pyqt5学习】——QAbstractButton学习(普通按钮QPushButton、工具按钮QToolButton、单选按钮QRadioButton、复选框按钮QCheckBox)

目录 1、按钮介绍 2、普通按钮QPushButton学习 1)特殊模式——开关按钮(toggle) ①将按钮设置为可选择的 ②将按钮按下 判断按钮是否被按下 isChecked() 2)给按钮设置前置图标setIcon() ​编辑 3)按钮信号 4)完…

挖财后端架构简介

挖财后端技术用的主要是比较大众的东西,Web容器用Tomcat,框架主要是Spring MVC,也有少量的Play,中间服务层是Dubbo,微容器用Spring Boot,服务注册这一块是用ZooKeeper,核心业务开发方式还是围绕…

【pyqt5学习】——QcomboBox学习

目录 1、添加条目: 1)逐一添加 2)批量添加 3)获取当前选中的索引 4)获取当前选中文本 5)根据索引获取文本 6)统计条目总数 7)信号——当前选中的索引发生改变currentIndexChanged() 2、…

vSphere Client 编辑虚拟机属性的问题

vSphere Client 编辑虚拟机属性的问题 编辑虚拟机属性的时候, 出现: vpxclient.vmconfig.cpuid 初始值设置异常之类的,重置了, 并将注册表中的所有vmvare 相关键值删除了, 还是一样的。。 后面参照https://kb.vmware.c…