关于代理模式和动态代理参考自:https://www.cnblogs.com/gonjan-blog/p/6685611.html

这里通过参考博客中的例子整理个人理解。

代理模式:

访问某个类的方法由直接调用方法,变为通过中间人练习。

即调用方➡功能提供者,变更为调用方➡代理人➡功能提供者。

这样做的好处:

1.调用方不再关注功能提供者的具体行为,专为代理人统一关注,调用方只用关注代理人的行为(接口)。

2.代理人可以在真正调用功能提供者的方法前后进行再加工提供部分行为。

静态代理:

在编译阶段已经知道代理人、功能提供者、调用方的关系。

动态代理:

代理人在编译阶段不知道调用方和功能提供者的类型,在运行时通过传入的参数动态建立代理关系。

因此动态代理的加工行为可以对拥有被代理人临时生效,比如计算任何功能提供者执行方法的时间。。

以下是例子:

静态代理:

Person接口代表所有学生,所有学生都有交班费的行为

package com.xdsux.java.proxy;

public interface Person {
//静态代理与功能提供者的统一接口
void giveMoney();
}

Student实现了Person接口的交班费行为:

package com.xdsux.java.proxy;

public class Student implements Person {

    @Override
public void giveMoney() {
System.out.println("学生提交班费:50"); } }

Monitor即代理(班长),班长可以找任何学生提交班费:

package com.xdsux.java.proxy;

public class Monitor implements Person {
//班长即代理,持有学生实例
Student stu; public Monitor(Person stu) {
this.stu = (Student)stu;
} @Override
public void giveMoney() {
//班长叫学生交班费
stu.giveMoney();
} }

测试,也就是老师叫班长去收班费:

package com.xdsux.java.proxy;

public class TestProxy {
public static void main(String[] args) {
//某学生
Student stu = new Student();
//某班长
Monitor mon = new Monitor(stu);
mon.giveMoney();
}
}

1.班长可以向任何一个学生收班费,在收取班费时可以加入其他动作,比如查询学生上次是否未交。

2.班长可以采用单例模式(一个班只有一个班长)

3.学生的缴费行为可以变动(学生出现子类贫困生,可能不需要交班费),但老师不必关心,班长负责和学生重新确定缴费行为,老师可以依然调用mon.giveMoney

动态代理

代理类需要实现InvovationHabdler接口:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class StuInvocationHandler<T> implements InvocationHandler { // 事先不知道代理谁
T target; public StuInvocationHandler(T target) {
this.target = target;
} /**
* proxy:代理动态对象 method:代表需要执行的方法 args:调用目标方法时要传入的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("代理执行" + method.getName() + "方法");
// 代理过程中插入监测方法,计算该方法耗时
MonitorUtil.start();
Object result = method.invoke(target, args);
MonitorUtil.finish(method.getName());
return result;
} }

代理会根据传入的实例和参数执行方法,并在每次代理时,计算目标方法的执行时间:

package com.xdsux.java.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; public class TestProxy {
public static void main(String[] args) {
//某学生
Student stu = new Student(); //创建一个与代理对象相关联的InvocationHandler
InvocationHandler stuHandler = new StuInvocationHandler<Person>(stu); //创建一个代理对象stuProxy来代理某学生,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler);
//代理执行上交班费的方法
stuProxy.giveMoney();
}
}

【Java】代理模式、反射机制-动态代理的更多相关文章

  1. Java反射机制动态代理

    1.什么事反射机制动态代理 在一段代码的前后动态执行其他操作,比如有一个方法是往数据库添加一个记录,我们可以通过动态代理,在操作数据库方法的前和后添加代码执行打开数据库连接和关闭数据库连接. 2.演示 ...

  2. Spring代理模式(jdk动态代理模式)

    有动态代理和静态代理: 静态代理就是普通的Java继承调用方法. Spring有俩种动态代理模式:jdk动态代理模式 和 CGLIB动态代理 jdk动态代理模式: 代码实现: 房东出租房子的方法(继承 ...

  3. Java高级特性—反射和动态代理

    1).反射 通过反射的方式可以获取class对象中的属性.方法.构造函数等,一下是实例: 2).动态代理 使用场景: 在之前的代码调用阶段,我们用action调用service的方法实现业务即可. 由 ...

  4. 代理模式之cglib动态代理

    上一篇博客说了实现InvocationHandler接口的jdk动态代理,还有一种实现动态代理的方式则是:通过继承的方式实现的cglib动态代理. 先在程序中导入cglib的包,cglib-nodep ...

  5. 代理模式及jdk动态代理原理

    代理模式 :为其它对象提供代理,以控制对这个对象的访问. 代理模式的特征:代理类(proxyClass)与委托类(realClass)有同样的接口,代理类主要负责为委托类预处理消息.过滤消息.把消息转 ...

  6. Java基础之反射和动态代理

    1,反射是依赖于Class对象,然后根据Class对象,去操作该类的资源的.Class对象是发射的基石! 问题1:人这类事物用什么表示?汽车这类事物用什么表示>计算机文件用什么表示?有如此多的事 ...

  7. java 27 - 9 反射之 动态代理的概述和实现

    代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象. 举例:春季回家买票让人代买 动态代理: 在程序运行过程中产生的这个对象 而程序运行过程中产生对象其实就是我们刚才反射讲解的内容,所以 ...

  8. java 代理模式二:动态代理

    java动态代理: java动态代理类位于java.lang.reflect包下,一般主要涉及两个类: 1.Interface InvocationHandler 该接口中仅定义了一个方法:Objec ...

  9. java 27 - 10 反射之 动态代理的代码实现

    为什么要写动态代理类? 例子: 如果现在想做个登陆注册的功能.用户可以执行登陆.注册.添加.删除这些功能. 但是,有些功能是要有一定权限才可以执行的. 而现在已经有了个用户类的接口和该类的实现类了,但 ...

随机推荐

  1. 关于mariad&mysql部分

    不赘述安装部分 查看安装的mysql版本 连接数据库基本操作: 查看数据库有没有运行: 退出操作:两者的区别就在于有无分号 或者: 查看已经安装的数据库: 新增用户并且赋予权限操作 MariaDB [ ...

  2. android 使用Retrofit2 RxJava 文件上传

    private static void upload(final Context context, final int type, File logFile) { Map<String, Req ...

  3. Pycharm 设置上下左右快捷键

    Pycharm的版本 Note:英文版的Pycharm,使用中文版的对照即可. 1. 打开Pycharm软件→File→Settings 2.Keymap→Editor Actions→搜索(up)→ ...

  4. 学习MeteoInfo二次开发教程(七)

    1.站点文件 12010615.syn在D:\Program Files (x86)\MeteoInfo\SampleSYNOP_Stations.csv在D:\Program Files (x86) ...

  5. 解决spring-security session超时 Ajax 请求没有重定向的问题

    开始时, 代码是这样的: $.ajax({ type : "POST", url : sSource, cache : false, dataType : "json&q ...

  6. __getattr__ __delattr__ __setattr__ __getattribute__使用(重写python提供的错误信息)

    自己定义了这些attr 查找删除设置就会触发自己定义的逻辑,如果不重新,pyton会提供自己报错信息class Room: def __init__(self,name): self.name = n ...

  7. 用react编写一个可以编辑的表格

    这只一个雏形,但是可以用了.难点是如何点击每行后面的编辑按钮,让当前行的格子都变成input. import {Component} from 'react' const Action = props ...

  8. MySQL 8.0 新增SQL语法对窗口函数和CTE的支持

    尝试了一下MySQL 8.0的部分新特性. 如果用过MSSQL或者是Oracle中的窗口函数(Oracle中叫分析函数), 然后再使用MySQL 8.0之前的时候,就知道需要在使用窗口函数处理逻辑的痛 ...

  9. elasticsearch template

    # curl -XPUT localhost:9200/_template/template_1 -d '{"template" : "te*","s ...

  10. Kivy 从memory 读取image

    借助PIL来处理的图片数据 fp = BytesIO() img = Image.frombytes('RGB', img_size, buf_bytes, 'raw', 'BGR;16', 0, 1 ...