https://blog.csdn.net/giserstone/article/details/17199755

代理的作用:业务类只需要关注业务逻辑本身,保证了业务类的重用性

一 静态代理

特点:

  程序运行前就已经存在代理类的字节码文件了,代理类和委托类的关系也在程序运行前就确定了 

实现:

  代理类继承了被代理类的接口;代理类将被代理类以成员变量的方式引入,在构造函数中初始化被代理类;共同接口中,引用成员变量的方法并在该接口中增加新功能以实现代理类的功能。

缺点:

  1)代理对象的一个接口只能服务于一种被代理对象,每有一种代理对象,就要多一个代理方法。

  2)代理类在程序一开始就要被加载,增加了内存负担

  3)如果接口类增加了一个方法,除了被代理对象要增加这个接口,代理对象也要增加这个接口,增加了程序维护的复杂度

  4)只能代理已知的对象

二 动态代理

特点:

  动态代理的字节码是在程序运行期间由JVM根据反射机制动态生成的,不存在代理类的字节码文件,代理类和委托类的关系是在程序运行时确定的

实现:

  1)实现InvocationHandler接口创建自己的调用处理器
  2)给Proxy类提供ClassLoader和代理接口类型数组创建动态代理类
  3)以调用处理器类型为参数,利用反射机制得到动态代理类的构造函数
  4) 以调用处理器对象为参数,利用动态代理类的构造函数创建动态代理类对象

demo:

接口:

package com.test.aoptest.proxyTest;

public interface MyTask {
void doing(); void writing();
}

委托类:

package com.test.aoptest.proxyTest;

public class MyTaskImpl implements MyTask {
@Override
public void doing() {
System.out.println("doing sth ...");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
} @Override
public void writing() {
System.out.println("writing sth ...");
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

调度器:

package com.test.aoptest.proxyTest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method; public class MyTaskInvocationHandler implements InvocationHandler { private Object delegate; public MyTaskInvocationHandler(Object delegate) {
this.delegate = delegate;
} @Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
long start = System.currentTimeMillis();
Object result = method.invoke(delegate, args);
long end = System.currentTimeMillis();
System.out.println("执行任务耗时"+(end - start)+"毫秒");
return result;
}
}

主入口:

package com.test.aoptest.proxyTest;

import java.lang.reflect.Proxy;

public class Client {
public static void main(String[] args) { MyTaskImpl myTask = new MyTaskImpl();
MyTask proxy = (MyTask) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(),
new Class[]{MyTask.class}, new MyTaskInvocationHandler(myTask));
proxy.doing();
proxy.writing();
// System.out.println(proxy.hashCode());
// System.out.println(myTask.hashCode());
// System.out.println(myTask.equals(proxy));
// System.out.println(myTask.toString());
// System.out.println(proxy.toString());
}
}

System.identityHashCode(Object) 返回对象的内存地址,不管该对象的类是否重写了hashCode()方法。

Java——静态代理、动态代理的更多相关文章

  1. java静态和动态代理原理

    一.代理概念 为某个对象提供一个代理,以控制对这个对象的访问. 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代.代理类负责请求的预处理.过滤.将请求分派给委托类 ...

  2. java 笔记(3) —— 动态代理,静态代理,cglib代理

    0.代理模式 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口. 代理类主要负责为委托类预处理消息.过滤消息.把消息转发给委托类,以及事后处理消息等. 代理类与委托类之间通常会存 ...

  3. 轻松理解 Java 静态代理/动态代理

    目录 什么是代理模式 定义 代理模式的主要角色 优点 缺点 静态代理 动态代理 JDK原生动态代理 例子 分析 小结 CGLIB动态代理 例子 分析 final类型 其他方案 尾声 理解Java动态代 ...

  4. Java 反射 设计模式 动态代理机制详解 [ 转载 ]

    Java 反射 设计模式 动态代理机制详解 [ 转载 ] @author 亦山 原文链接:http://blog.csdn.net/luanlouis/article/details/24589193 ...

  5. 【SSH系列】静态代理&&动态代理

    从设计模式说起 代理模式是二十三中设计模式中的一种,代理模式就是指由一个代理主题来操作真实的主题,真实的主题执行具体的业务操作,而代理主题负责其她相关业务,简而言之,代理模式可以由以下三个部分组成: ...

  6. 细说java系统之动态代理

    代理模式 在深入学习动态代理之前,需要先掌握代理模式.只有深刻理解了代理模式的应用,才能充分理解Java动态代理带来的便利. 在生活中存在许多使用"代理模式"的场景,比如:村里的张 ...

  7. 杨晓峰-Java核心技术-6 动态代理 反射 MD

    目录 第6讲 | 动态代理是基于什么原理? 典型回答 考点分析 知识扩展 反射机制及其演进 动态代理 精选留言 Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAnd ...

  8. 十分钟理解Java中的动态代理

    十分钟理解 Java 中的动态代理   一.概述 1. 什么是代理 我们大家都知道微商代理,简单地说就是代替厂家卖商品,厂家“委托”代理为其销售商品.关于微商代理,首先我们从他们那里买东西时通常不知道 ...

  9. 静态代理,动态代理,Cglib代理详解

    一.静态代理 新建一个接口 定义一个玩家方法: package com."".proxy.staticc; public interface Iplayer { public vo ...

  10. 深度剖析java中JDK动态代理机制

    https://www.jb51.net/article/110342.htm 本篇文章主要介绍了深度剖析java中JDK动态代理机制 ,动态代理避免了开发人员编写各个繁锁的静态代理类,只需简单地指定 ...

随机推荐

  1. group_by和having的用法

    #encoding: utf-8 from sqlalchemy import create_engine,Column,Integer,String,Float,func,and_,or_,Enum ...

  2. The Maze

    There is a ball in a maze with empty spaces and walls. The ball can go through empty spaces by rolli ...

  3. Shell初学(七)linux账户管理/群组管理

    [1]新建用户 用户相关文件:/etc/passwd  /etc/shadow useradd useradd的默认预设 [2]设置密码 passwd 常见修改密码使用技巧: echo "1 ...

  4. java解析json字符串详解(两种方法)

    一.使用JSONObject来解析JSON数据官方提供的,所以不需要导入第三方jar包:直接上代码,如下 private void parseJSONWithJSONObject(String Jso ...

  5. 全面解析java编码问题

    1.web.xml文件里配置 <filter> <filter-name>CharacterEncodingFilter</filter-name> <fil ...

  6. shiro登陆流程

    登录请求被FormAuthenticationFilter拦截 FormAuthenticationFilter会执行其父类AdviceFilter的doFilterInternal方法 其代码如下: ...

  7. git简易操作手册

    从远程仓库新建 $ git clone https://github.com/xxxr/Repository.git $ cd Repository/ $ git config --global us ...

  8. 部署k8s集群之环境搭建和etcd单节点安装

    环境搭建以及etcd 单节点安装过程 安装之前的环境搭建 在进行k8s安装之前先把虚拟机准备好,这里准备的是三台虚拟机 主机名 ip地址 角色 master 172.16.163.131 master ...

  9. Zookeeper VS Chubby

    目录 区别的根源      1)一致性      2)Client Cache vs No Cache 总结 参考资料 区别的根源 一个设计良好的系统应该是围绕并为其设计目标服务的. Chubby:p ...

  10. 安装MySQL数据库并开启远程访问

    一.安装MySQL数据库 MySQL安装在系统盘下(C:\Program Files),方便系统备份. 1.双击安装程序,勾选“I accept the license terms”,点击“Next” ...