java反射机制应用之动态代理
1.静态代理类和动态代理类区别
静态代理:要求被代理类和代理类同时实现相应的一套接口;通过代理类的对象调用重写接口的方法时,实际上执行的是被代理类的同样的
方法的调用。
动态代理:在程序运行时,根据被代理类及其实现的接口,动态的创建一个代理类。当调用代理类的实现的抽象方法时,就发起对被代理类同样方法的调用。
涉及到的技术点:
①提供一个实现了InvocationHandler接口实现类,并重写其invoke()方法
②Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),h);
2.动态代理的优点
它可以在程序运行时动态的为任何想要被代理的类生成代理对象(代理对象中包含了编写的通用代理逻辑),它不用去关心被代理的类到底是怎样的,可以与被代理的类完全脱离关系,从而灵活的运用到不同的应用场景中。
下面通过具体的代码来体现动态代理的好处
第一个是静态代理的代码
package 反射机制;
//静态代理特征是代理类和目标对象的类都是在编译期间确定下来的
//不利于程序的扩展。同时,每一个代理类只能为一个接口服务,这样一来
//程序开发必然产生过多的代理
//接口
interface ClothProduct{
void productCloth();
}
//被代理类
class NikeClothFactory implements ClothProduct{
@Override
public void productCloth() {
System.out.println("nike生产一批衣服");
}
}
//代理类
class ProxyFactory implements ClothProduct{
ClothProduct cf;
//创建代理类的对象时,实际传入一个被代理类的对象
public ProxyFactory(ClothProduct cf) {
this.cf=cf;
}
@Override
public void productCloth() {
System.out.println("代理类开始执行");
cf.productCloth();
}
}
public class JingTaiDaiLi {
public static void main(String[] args) {
NikeClothFactory nc=new NikeClothFactory();
ProxyFactory proxy=new ProxyFactory(nc);
proxy.productCloth();
}
}
//每建立一个被代理类就必须建立一个代理类,则多个被代理类就得写多个代理类太麻烦
下面是动态代理类
package 反射机制;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//动态代理是指客户通过代理类来调用其他对象的方法,
//并且是在程序运行时根据需要动态创建目标类的代理对象
interface Subject{
void action();
}
//被代理类
class RealSubject implements Subject{
public void action()
{
System.out.println("我是被代理类");
}
}
class MyIvocationHandler implements InvocationHandler{
Object obj;//实现了接口的被代理类的对象的声明
//给被代理类的对象实例化,返回一个代理类的对象
public Object blind(Object obj) {
this.obj=obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this) ;
}
//当通过代理类的对象发起对重写的方法调用时都会转化为对如下的Invoke方法的调用
@Override
public Object invoke(Object arg0, Method arg1, Object[] arg2) throws Throwable {
Object obj1=arg1.invoke(obj, arg2);
return obj1;
}
}
public class DongTaiDaiLi {
public static void main(String[] args) {
//被代理类的对象
RealSubject rs=new RealSubject();
//2创建一个实现实现IvocationHandler接口的类的对象
MyIvocationHandler mh=new MyIvocationHandler();
//3调用blind()方法,动态的返回一个同样实现real所在类的接口subject的代理类的对象
Object obj=mh.blind(rs);
Subject sub=(Subject)obj;//此时sub就是代理类对象
sub.action();//转到IvocationHandler接口的实现类的invoke()方法的调用
System.out.println();
//利用静态代理的被代理类体现动态代理
NikeClothFactory Nick=new NikeClothFactory();
//ClothProduct cp=new ClothProduct();
ClothProduct cp=(ClothProduct)mh.blind(Nick);
cp.productCloth();
}
}
所有被代理类都对应一个代理类,当通过代理类的对象发起对重写的方法调用时都会转化为对唯一一个代理类的Invoke方法的调用,不同的被代理类对应不同的method,所以invoke方法是动态变化的,,方便对多个被代理类的代理。。
java反射机制应用之动态代理的更多相关文章
- java 反射之静态and动态代理
首先说一下我们什么情况下使用代理? (1)设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the c ...
- 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换
作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...
- Java 反射机制(一)
阅读<Core Java Volume I --- Fundamentals>反射部分,总觉得许多概念艰涩难懂.模棱两可.我想造成这个结果的主要原因可能是Cay S. Horstmann和 ...
- Java反射机制剖析(四)-深度剖析动态代理原理及总结
动态代理类原理(示例代码参见java反射机制剖析(三)) a) 理解上面的动态代理示例流程 a) 理解上面的动态代理示例流程 b) 代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...
- Java反射机制剖析(三)-简单谈谈动态代理
通过Java反射机制剖析(一)和Java反射机制剖析(二)的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制. 1. 代理模式 代理模式就是为其他对象提供一种代理来 ...
- java反射机制与动态代理
在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...
- Java反射机制以及动态代理
Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...
- java反射机制与动态加载类
什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...
- Java反射机制可以动态修改实例中final修饰的成员变量吗?
问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...
随机推荐
- <raspberry pi > 用树莓派来听落网电台
树莓派放在抽屉里吃灰有半年多了,去年玩了1个月后就没怎么开整了,上个月没工作,刚好有点闲暇,就把树莓派翻出来折腾,刚好碰到落网改版了,想起以前在树莓派论坛看到有网友拿树莓派来听豆瓣电台,代码那时我都下 ...
- Docker实践中遇到的坑
1.docker容器中后台运行退出执行curl+p+q,再次进入执行命令docker attach 容器id. 2.容器中exit退出后,还原方法为docker ps -a 查看历史运行容器,dock ...
- API的理解和使用——键管理
核心知识点: 1.键重命名:rename和renamenx,使用renamenx时newkey必须不存在,重命名后会使用del删除原来的键,如果值比较大也会会造成阻塞. 2.随机返回一个值:rando ...
- web项目中从不同的路径读取文件
项目中的配置文件可以放在classpath下,webapp下获取其他任何一个指定的绝对地址,读取这些文件就从这三个地方去找.主要代码如下: private List<String> get ...
- windows下创建做一个类似与linux 的SFTP
在项目中经常需要做通过ftp上传文件到ftp上,如果服务器是windows版的服务器又该如何做呢,下面就给大家介绍一个软件:freeSSHd 软件地址 http://www.freesshd.c ...
- matlab的数组
1.定义:同一类型的元素的集合. 2.生成:用[]创建,元素之间用逗号或者空格隔开. 第一例: >>a=[1,2,3,4] a = 1 2 3 4 注意,取矩阵的某几列,是这样a(:,2: ...
- cocos2d-x中CCScrollView纵向展示
最近写CCScrollView遇到很多问题,样式是竖直的类似tableview,在此记录下: CCLayer* layer; 初始化scrollview内容器层 layer = CCLayer::cr ...
- JavaScript(4)
myfuns.js //自定义函数 //输入两个数,再输入一个运算符(+,-,*,/),得到结果->函数 function jiSuan(num1,num2,operator){//特别强调 参 ...
- Centos 6.3 编译安装Nginx+php+Mysql
1.配置防火墙,开启80端口.3306端口 vi /etc/sysconfig/iptables 将 -A INPUT -m state --state NEW -m tcp -p tcp --dpo ...
- 通过阿里云域名动态解析 IP 地址
这两天在家里用树莓派折腾了一个家用服务器,主要用来做 mac 的 Time Machine ,还有就是当做下载机和 nas ,想着平时上班时间家里没人用网络,空着也是空着,就可以利用空闲带宽下个美剧啥 ...