JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(3):常用动态代理之JDK动态代理、CGLIB动态代理
一、动态代理的理解
动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问。
先来谈谈什么是代理模式。
假设这样一个场景:你的公司是一家软件公司,你是一位软件工程师。客户带着需求去找公司显示不会直接和你谈,而是找商务谈,此时客户认为商务代表公司。

显然客户是通过商务区访问软件工程师的,那么商务(代理对象)的意义在于什么呢?
商务可以进行谈判,比如项目启动前的商务谈判,软件的价格,交付,进度的时间节点等,或者项目完成后的商务追讨应收账务等。商务有可能谈判失败,此时商务就会根据公司规则去结束和客户的合作关系,这些都不用工程师来处理。
因此,代理的作用就是,在真实对象访问之前后者之后加入对应的逻辑,或者根据其他规则控制是否使用真实对象,显然在这个例子里商务控制了客户对软件工程师的访问。
经过上面的论述,我们知道上午和软件工程师是代理和被代理的关系。客户经过商务区访问工程师。此时客户就是程序的调用者,商务就是代理对象,工程师就是真实对象。我们需要在调用者调用对象之前产生一个代理对象,而这个代理对象需要和真实对象建立代理关系,所以我们代理必须分为两个步骤:
(1)代理对象和真实对象之间建立代理关系。
(2)实现代理对象的代理逻辑方法。
二、常用的动态代理
在Java中有多种代理技术,比如:JDK、CGLIB、Javassist、ASM,其中最常用代理技术有两种:一种是JDK动态代理,这是JDK自带的功能,另一种是CGLIB,这是第三方提供的技术。目前Spring常用JDK和CGLIb,而MyBatis还使用了Javassist,但是无论哪种技术,它们的理念是相似的。
三、JDK动态代理(测试)
创建一个接口:HelloWorld.java
package com.xfwl.proxy;
public interface HelloWorld {
public void sayHelloWorld();
}
创建一个实现子类:HelloWorldImpl.java
package com.xfwl.proxy;
public class HelloWorldImpl implements HelloWorld {
public void sayHelloWorld() {
System.out.println("Hello World!");
}
}
创建一个代理类:JdkProxyExample.java
package com.xfwl.proxy; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* JDK的动态代理
* @function 两个步骤:(1)建立代理对象和真实服务对象的关系。(2)实现代理逻辑。
* @author 小风微凉
* @time 2018-7-9 上午10:45:53
*/
public class JdkProxyExample implements InvocationHandler {
//真实对象
private Object target=null;
/**
* 建立代理对象和真实对象之间的代理关系,并返回代理对象
* @param target 真实对象
* @return 代理对象
*/
public Object bind(Object target){
this.target=target;
return Proxy.newProxyInstance(
target.getClass().getClassLoader(), //类加载器
target.getClass().getInterfaces(), //动态代理所挂的接口
this //实现方法逻辑的代理类,必须实现InvocationHandler接口的invoke方法
);
}
/**
* 代理方法逻辑
* @param proxy 代理对象
* @param method 当前调度方法
* @param args 当前方法参数
* @return 代理结果返回
* @throws Throwable 异常
*/
public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
System.out.println("进入代理方法");
System.out.println("在调度真实方法之前的服务");
Object obj=method.invoke(this.target, args);//相当于调用sayHelloWorld方法
System.out.println("在调度真实方法之后的服务");
return obj;
}
}
创建一个测试类:TestProxy.java
package com.xfwl.proxy;
/**
* 测试JDK代理
* @function 分析JDK是如何实现代理的
* @author 小风微凉
* @time 2018-7-9 上午10:47:14
*/
public class TestProxy {
/**
* 测试入口
*/
public static void main(String[] args) {
JdkProxyExample jdk=new JdkProxyExample();
//绑定关系,因为挂在接口HelloWorld下,所以生命代理对象HelloWorld proxy
HelloWorld proxy=(HelloWorld)jdk.bind(new HelloWorldImpl());
//注意,此时HelloWorld对象已经是一个代理对象,它会进入代理的逻辑方法invoke里
proxy.sayHelloWorld();
}
}
测试结果:
进入代理方法
在调度真实方法之前的服务
Hello World!
在调度真实方法之后的服务
四、CGLIB动态代理(测试)
待续。。。。。。。。。。。。。
五、总结一下
待续。。。。。。。。。。。。。
JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(3):常用动态代理之JDK动态代理、CGLIB动态代理的更多相关文章
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解
一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解
一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件
一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)
一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)
一. 装配Bean概述 关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配
一.依赖注入的三种方式 在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)
一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)
一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean
一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...
- JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式
一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景. 2. ...
随机推荐
- 基于jwt和角色的访问控制方案-从0开始
上一版本的构想:http://www.cnblogs.com/vhyc/p/7953779.html 缺陷:dubbo的filter里面不能注入mapper的bean,而且每次查询都访问数据库速度影响 ...
- python-mao
冒泡排序算法的运作如下: 比较相邻的元素.如果第一个比第二个大,就交换他们两个. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对.在这一点,最后的元素应该会是最大的数. 针对所有的元素重复 ...
- 安卓apk包重复签名问题
安卓数字签名指的是对apk包做文件摘要并加密,在安装apk包时做解密和验证以保证包体不被篡改.这里先普及下签名和验证流程.签名文件保存在apk包里META-INF目录下,包含3个文件: 1.后缀为MF ...
- 对于global的介绍
抄自http://veniceweb.googlecode.com/svn/trunk/public/daily_tech_doc/erlang_global_20091109.txt 1. 介绍:这 ...
- distinct与order by
不知为啥,当我得查询中出现distinct时,order by 中必须包含要查询的列,否则报错. SELECT DISTINCT a.DetailId, a.OrderId, a.ProductId, ...
- Linux - apache 服务
暂时关闭 iptables 防火墙 [root@sch01ar ~]# systemctl stop iptables.service 暂时关闭 firewall 防火墙 [root@sch01ar ...
- 深度剖析collections模块
namedtuple OrderedDict deque tuple defaultdict Counter ChainMap
- log4net 入门教程
1.下载dll 下载地址:http://mirror.reverse.net/pub/apache/logging/log4net/binaries/ github:https://github.co ...
- <转>Linux环境进程间通信--信号灯(四)
http://www.ibm.com/developerworks/cn/linux/l-ipc/part4/ 一.信号灯概述 信号灯与其他进程间通信方式不大相同,它主要提供对进程间共享资源访问控制机 ...
- Resin 的watchdog(看门狗)介绍和resin负载均衡实现
为了稳定和安全,Resin使用一个独立的watchdog进程来启动和监视Resin服务器.watchdog连续你检测Resin服务器的状态,如果其没有反应或者迟钝,将会重启Resin服务器进程.大多数 ...