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反射机制应用之动态代理的更多相关文章

  1. java 反射之静态and动态代理

    首先说一下我们什么情况下使用代理? (1)设计模式中有一个设计原则是开闭原则,是说对修改关闭对扩展开放,我们在工作中有时会接手很多前人的代码,里面代码逻辑让人摸不着头脑(sometimes the c ...

  2. 利用java反射机制 读取配置文件 实现动态类载入以及动态类型转换

    作者:54dabang 在spring的学习过程之中,我们能够看出通过配置文件来动态管理bean对象的优点(松耦合 能够让零散部分组成一个总体,而这些总体并不在意之间彼此的细节,从而达到了真正的物理上 ...

  3. Java 反射机制(一)

    阅读<Core Java Volume I --- Fundamentals>反射部分,总觉得许多概念艰涩难懂.模棱两可.我想造成这个结果的主要原因可能是Cay S. Horstmann和 ...

  4. Java反射机制剖析(四)-深度剖析动态代理原理及总结

    动态代理类原理(示例代码参见java反射机制剖析(三)) a)  理解上面的动态代理示例流程 a)  理解上面的动态代理示例流程 b)  代理接口实现类源代码剖析 咱们一起来剖析一下代理实现类($Pr ...

  5. Java反射机制剖析(三)-简单谈谈动态代理

    通过Java反射机制剖析(一)和Java反射机制剖析(二)的学习,已经对反射有了一定的了解,这一篇通过动态代理的例子来进一步学习反射机制. 1.     代理模式 代理模式就是为其他对象提供一种代理来 ...

  6. java反射机制与动态代理

    在学习HadoopRPC时.用到了函数调用.函数调用都是採用的java的反射机制和动态代理来实现的,所以如今回想下java的反射和动态代理的相关知识. 一.反射 JAVA反射机制定义: JAVA反射机 ...

  7. Java反射机制以及动态代理

    Java反射机制以及动态代理 Java反射机制 含义与功能 Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类 ...

  8. java反射机制与动态加载类

    什么是java反射机制? 1.当程序运行时,允许改变程序结构或变量类型,这种语言称为动态语言.我们认为java并不是动态语言,但是它却有一个非常突出的动态相关机制,俗称:反射. IT行业里这么说,没有 ...

  9. Java反射机制可以动态修改实例中final修饰的成员变量吗?

    问题:Java反射机制可以动态修改实例中final修饰的成员变量吗? 回答是分两种情况的. 1. 当final修饰的成员变量在定义的时候就初始化了值,那么java反射机制就已经不能动态修改它的值了. ...

随机推荐

  1. django mysql setting 设置

    django mysql setting  django mysql 设置 DATABASES = {    'default': {        'ENGINE': 'django.db.back ...

  2. ABAP div / mod的用法

    1.divdiv是用于取两数相除的商的,c = a div b,得到的c的值就是a除b的商.2.// 是用于取两数相除的结果的.c = a / b,如果c是i数据类型的,这个语法会进行四舍五入的.3. ...

  3. java基础语言 运算符

    /* ++,--运算符的使用: 单独使用: 放在操作数的前面和后面效果一样.(这种用法是我们比较常见的) 参与运算使用: 放在操作数的前面,先自增或者自减,然后再参与运算. 放在操作数的后面,先参与运 ...

  4. MySQL——并发控制(锁)

    核心知识点: 1.表锁和行级锁代表着锁的级别:读锁和写锁代表锁定真实类型. 2.读锁属于共享锁,共享同一资源,互不干扰:写锁属于排他锁,为了安全起见,写锁会阻塞其他的读锁和写锁. 3.表锁的开销最小, ...

  5. API的理解和使用——全局命令

    全局命令 命令 功能 set 创建键值对 keys 遍历查看所有键 exists 判断一个键是否存在,1存在,0不存在 dbsize 当前数据库中有多少个键 del 删除一个或多个键 expire 设 ...

  6. ls bash: cannot create temp file for here-document: No space left on device

    出现这种问题,一般是磁盘空间满了,或者是inode满了 使用命令: df -h查询磁盘空间 df -i 查询inode占用 Filesystem Inodes IUsed IFree IUse% Mo ...

  7. linux 防火墙配置与REJECT导致没有生效问题

    1.进入到/etc/sysconfig 如图 2.使用vi命令对iptables进行编辑."vi iptables",然后显示如图 # Firewall configuration ...

  8. hadoop 安装配置

    1.伪分布式搭建: 步骤参考: http://wenku.baidu.com/link?url=N_Sc7dqaO5HB47SmhntYZQI2tvvAjYt0mWT0fx28FDSMRYKTLUTc ...

  9. ubuntu tomcat 配置及使用细节

    1.改端口号(两个) vi server.xml 一个是http协议端口  <Connector port="8091" protocol="HTTP/1.1&qu ...

  10. 五子棋AI的思路

    隔了一年才把AI思路给写了... 需求分析与设计方案:http://www.cnblogs.com/songdechiu/p/4951634.html 如需整个工程,移步http://download ...