一、动态代理的理解  

动态代理的意义在于生成一个占位(又称代理对象),来代理真实对象,从而控制真实对象的访问。
        先来谈谈什么是代理模式。
        假设这样一个场景:你的公司是一家软件公司,你是一位软件工程师。客户带着需求去找公司显示不会直接和你谈,而是找商务谈,此时客户认为商务代表公司。

显然客户是通过商务区访问软件工程师的,那么商务(代理对象)的意义在于什么呢?
商务可以进行谈判,比如项目启动前的商务谈判,软件的价格,交付,进度的时间节点等,或者项目完成后的商务追讨应收账务等。商务有可能谈判失败,此时商务就会根据公司规则去结束和客户的合作关系,这些都不用工程师来处理。
因此,代理的作用就是,在真实对象访问之前后者之后加入对应的逻辑,或者根据其他规则控制是否使用真实对象,显然在这个例子里商务控制了客户对软件工程师的访问。
        经过上面的论述,我们知道上午和软件工程师是代理和被代理的关系。客户经过商务区访问工程师。此时客户就是程序的调用者,商务就是代理对象,工程师就是真实对象。我们需要在调用者调用对象之前产生一个代理对象,而这个代理对象需要和真实对象建立代理关系,所以我们代理必须分为两个步骤:

(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动态代理的更多相关文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(2):SSM+Redis概念理解

    一.SSM+Redis的结构图 在Java互联网中,以Spring+SpringMVC+MyBatis(SSM)作为主流框架,SSM+Redis的结构图如下: 二.下面介绍它们各自承担的功能: 1.S ...

  2. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解

    一.关键字说明: oop:面向对象 aop:面向切面 ioc:控制反转 orm:对象关系映射 pojo:数据库表映射的java实体类 二.常识说明:1.hibernate和mybatis都属于持久层. ...

  3. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(12):XML配置自动扫描包,自动加载*.properties文件

    一.XML和注解组合使用 前几篇的测试案例都是在Java类中配置,现在换一种使用方式,在XML中配置,使Spring IoC容器在启动之后自动去扫描配置的包路径,扫描加载指定路径下的propertie ...

  4. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(10):通过注解(annotation)装配Bean之(@Configguration、@Component、@Value、@ComponentScan、@Autowired、@Primary、@Qualifier、@Bean)

    一.通过注解(annotation)装配Bean 通过之前的学习,我们已经知道如何使用XML装配Bean,但是更多的时候已经不再推荐使用XML的方式去装配Bean,更多的时候会考虑注解(annotat ...

  5. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(8):装配SpringBean概述(如何合理使用装配级别)

    一. 装配Bean概述  关于如何将自己开发的Bean配置到Spring IoC容器中,大部分场景下,我们都会使用ApplicationContext的具体实现类,因为对应的Spring IoC容器功 ...

  6. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(7):装配SpringBean·依赖注入装配

    一.依赖注入的三种方式      在实际环境中实现IoC容器的方式主要分为两大类,一类是依赖查找,依赖查找是通过资源定位,把对应的资源查找回来.另一类则是依赖注入.一般而言,依赖注入可分为3中方式: ...

  7. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(6):Spring IOC容器学习(概念、作用、Bean生命周期)

    一.IOC控制反转概念 控制反转(IOC)是一种通过描述(在Java中可以是XML或者是注解)并通过第三方去生产或获取特定对象的方式. 主动创建模式,责任在于开发者,而在被动模式下,责任归于Ioc容器 ...

  8. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(11):XML和Annotation装配Bean的混合使用(@ImportResource)

    一.XML和Annotation装配Bean如何合理使用 引入第三方资源包中类的时候,建议使用XML配置,而使用自己编写的Java类的时候,推荐使用Annotation注解配置Bean. 二.关于注解 ...

  9. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(9):通过XML装配Bean

    一.通过XML装配Bean 装配简易值 装配集合 命名空间装配(暂不测试) 二.测试例子 创建一个用户类:UserBean.java package com.xfwl.spring.assem; /* ...

  10. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(5):责任链模式、观察者模式

    一.责任链模式.观察者模式 1.责任链模式:当一个对象在一条链上被多个拦截器处理(烂机器也可以选择不拦截处理它)时,我们把这样的设计模式称为责任链模式,它用于一个对象在多个角色中传递的场景.   2. ...

随机推荐

  1. hbase官方文档(转)

    FROM:http://www.just4e.com/hbase.html Apache HBase™ 参考指南  HBase 官方文档中文版 Copyright © 2012 Apache Soft ...

  2. 如何让公司从SVN改到Git?

    把公司的SVN迁移到GitLab CE(GitLab社区版)原因主要有下面几个: 年青的新人进来,喜欢用git的越来越多 GitLab CE提供了优美的 web 界面,图形化分支结构,更直观的代码审查 ...

  3. Oracle存储过程使用总结

    1.使用Oracle存储过程查询结果集: 网上写的都是他妈的扯淡!其实一句话就行了,你只要返回一个游标就OK了.具体代码如下: CREATE OR REPLACE PROCEDURE PR_ORDER ...

  4. log4net内部调试开启

    最近用log4net写入日志到mysql数据库,死活写不进去,就想能不能看log4net的错误记录,在网上一找,还真有:开启log4net的内部调试,作个记录: <appSettings> ...

  5. mac 在终端使用命令行启动脚本,无法使用自己安装的python去执行脚本问题

    参考了2片文章: //查看python位置 which python //先备份 1.sudo cp /usr/bin/python /usr/bin/python_cp //删除 2.sudo rm ...

  6. Effective java笔记3--类和接口1

    一.使类和成员的可访问能力最小化 要想区别一个设计良好的模块与一个设计不好的模块,最重要的因素是,这个模块对于外部的其他模块而言,是否隐藏了内部的数据和其他的实现细节.一个设计良好的模块会隐藏所有的实 ...

  7. Java标准I/O流介绍

    1.I/O是什么? I/O 是Input/Output(输入.输出)的简称,输入流可以理解为向内存输入,输出流是从内存输出. 2.流 流是一个连续的数据流,可以从流中读取数据,也可以往流中写数据.流与 ...

  8. java实现递归(1)

    1.递归算法基本思路: Java递归算法是基于Java语言实现的递归算法.递归算法是一种直接或者间接调用自身函数或者方法的算法.递归算法实质是把问题分解成规模缩小的同类问题的子问题,然后递归调用方法表 ...

  9. 参数传递中编码问题(Get/Post 方式)(三)

    自己总结的:     GET方式:      1.提交方式为GET时,数据是放在请求HEADER头中的,且将数据与URL拼接后,浏览器会对拼接后的url进行编码,编码方式为浏览器默认的编码,      ...

  10. a标签的四个伪类是什么?如何排序?为什么?

    爱恨分明原则: l v h a 注释:为了产生预期的效果,在 CSS 定义中,a:hover 必须位于 a:link 和 a:visited 之后 ! 注释:为了产生预期的效果,在 CSS 定义中,a ...