静态代理的缺点是在代理类中绑定了固定的接口,不利于扩展,动态代理则不然,通过动态代理能够对不论什么实现某一接口的类进行功能性增强。

在java中动态代理由InvocationHander来实现。

HelloInterface接口

[java] view
plain
copy

  1. package proxy;
  2. public interface HelloInterface {
  3. public void sayHello();
  4. }

实现HelloInterface接口的类HelloInterfaceImpl



[java]
 view
plain
copy

  1. package proxy;
  2. public class HelloInterfaceImpl implements HelloInterface {
  3. @Override
  4. public void sayHello() {
  5. System.out.println("Hello xianjj");
  6. }
  7. }

proTest类实现了InvocationHandler类

package proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 实现InvocationHandler接口
public class proTest implements InvocationHandler { Object anyObject; // 申明bind方法
public Object bind (Object anyObject){
this.anyObject = anyObject;
return Proxy.newProxyInstance(anyObject.getClass().getClassLoader(), anyObject.getClass().getInterfaces(), this);
}
// 重写invoke方法
@Override
public Object invoke(Object arg0, Method arg1, Object[] args)
throws Throwable {
Object returnObject = null;
System.out.println("动态代理開始");
returnObject = arg1.invoke(anyObject, args);
System.out.println("动态代理结束");
return returnObject;
} public static void main(String[] args) {
proTest proTest = new proTest();
HelloInterface helloInterfaceReturn = (HelloInterface)proTest.bind(new HelloInterfaceImpl());
helloInterfaceReturn.sayHello();
}
}

在main方法中调用proTest对象的bind绑定方法将一个实现类与一个动态代理进行绑定。动态代理主要由下面代码来实现

Proxy.newProxyInstance(anyObject.getClass().getClassLoader(), anyObject.getClass().getInterfaces(), this);

将输入的anyObject对象与接口进行动态关联。这样就能够避免静态接口固定的缺陷了,动态代理由原来的静态代理面向接口转向动态代理面向实现类,这样设计的出发点不是对接口,而是动态的取的接口。软件的灵活性大大的提高。

当调用被代理的HelloInterfaceImpl类实例的方法时,系统将转到包括代理类proTest的InvocationHandler的invoke方法中运行对应的代码,动态代理的过程结束。

public class proTest implements InvocationHandler类不在服务于某一个接口。静态代理和动态代理都是针对于sayHello()方法进行增强,不支持field字段级的增强。

Spring觉得那已经在破坏面向对象编程的结构,所以支持方法的增强是再合适不的,并且与Spring的其它模块进行整合开发时会更有集中性。

结果:

Spring2.5学习4.2_Proxy实现动态代理(目标类实现随意接口)的更多相关文章

  1. Spring学习笔记之aop动态代理(3)

    Spring学习笔记之aop动态代理(3) 1.0 静态代理模式的缺点: 1.在该系统中有多少的dao就的写多少的proxy,麻烦 2.如果目标接口有方法的改动,则proxy也需要改动. Person ...

  2. Java反射学习总结四(动态代理使用实例和内部原理解析)

    通过上一篇文章介绍的静态代理Java反射学习总结三(静态代理)中,大家可以发现在静态代理中每一个代理类只能为一个接口服务,这样一来必然会产生过多的代理,而且对于每个实例,如果需要添加不同代理就要去添加 ...

  3. 学习CGLIB与JDK动态代理的区别

    动态代理 代理模式是Java中常见的一种模式.代理又分为静态代理和动态代理.静态代理就是显式指定的代理,静态代理的优点是由程序员自行指定代理类并进行编译和运行,缺点是一个代理类只能对一个接口的实现类进 ...

  4. 为什么JDK动态代理中要求目标类实现的接口数量不能超过65535个

    先明确几个概念: Class文件是一组以8字节为基础单位的二进制流 各个数据项目严格按照顺序紧凑排列在class文件中 中间没有任何分隔符,这使得class文件中存储的内容几乎是全部程序运行的程序 J ...

  5. Hibernate学习--hibernate延迟加载原理-动态代理(阿里电面)

    在正式说hibernate延迟加载时,先说说一个比较奇怪的现象吧:hibernate中,在many-to-one时,如果我们设置了延迟加载,会发现我们在eclipse的调试框中查看one对应对象时,它 ...

  6. JDK动态代理为什么必须要基于接口?

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 前几天的时候,交流群里的小伙伴抛出了一个问题,为什么JDK的动态代理一定要基于接口实现呢? 好的安排,其实要想弄懂这个问题还是需要一些关于代理和 ...

  7. cgkib动态代理详解-不依赖接口,速度快

    1. cglib原理-不依赖接口,速度快 使用ASM字节框架动态生成要代理类的子类,子类重写final以外的方法,织入横切逻辑 2. 示例-实现MethodInterceptor Test.java ...

  8. 【Java EE 学习 51】【Spring学习第三天】【cglib动态代理】【AOP和动态代理】【切入点表达式】

    一.cglib动态代理 1.简介 (1)CGlib是一个强大的,高性能,高质量的Code生成类库.它可以在运行期扩展Java类与实现Java接口. (2) 用CGlib生成代理类是目标类的子类. (3 ...

  9. Spring的两种代理方式:JDK动态代理和CGLIB动态代理

    代理模式 代理模式的英文叫做Proxy或Surrogate,中文都可译为”代理“,所谓代理,就是一个人或者一个机构代表另一个人或者另一个机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一个对 ...

随机推荐

  1. CentOS7网络自动连接

    1)在root用户下使用命令"vim /etc/sysconfig/network-scripts/ifcfg-XXX",其中"ifcfg-XXX"的" ...

  2. Check if a user is in a group

    groups or groups user

  3. MTK平台源码 mt6589-jb3-x_20131122

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha

  4. 【20181019T3】比特战争【最小生成树思想】

    题面 [错解] Hmm不可做啊 要不按b排个序? 然后并查集瞎搞,刷刷刷过了样例 然后大样例大了几万倍 出了组小数据,Successful Hack 弃疗 水过10分 [正解] 用占领的边将顶点连起来 ...

  5. Codeforces Round #453 ( Div. 2) Editorial ABCD

    A. Visiting a Friend time limit per test 1 second memory limit per test 256 megabytes input standard ...

  6. 【DFS】【打表】Lattice Animals

    [ZOJ2669]Lattice Animals Time Limit: 5 Seconds      Memory Limit: 32768 KB Lattice animal is a set o ...

  7. 【二分】【字符串哈希】【二分图最大匹配】【最大流】XVII Open Cup named after E.V. Pankratiev Stage 14, Grand Prix of Tatarstan, Sunday, April 2, 2017 Problem I. Minimum Prefix

    给你n个字符串,问你最小的长度的前缀,使得每个字符串任意循环滑动之后,这些前缀都两两不同. 二分答案mid之后,将每个字符串长度为mid的循环子串都哈希出来,相当于对每个字符串,找一个与其他字符串所选 ...

  8. 【rope】bzoj1269 [AHOI2006]文本编辑器editor

    维护一个字符串,支持以下操作:   主要就是 成段插入.成段删除.成段翻转.前两个操作很好通过rope实现.第三个操作也不难,维护两个rope,一个正向,一个反向,翻转时swap一下就行了.   ro ...

  9. 广义线性模型(logistic和softmax)

    再谈广义线性模型之前,先来看一下普通线性模型: 普通线性模型的假设主要有以下几点: 1.响应变量Y和误差项ϵ正态性:响应变量Y和误差项ϵ服从正态分布,且ϵ是一个白噪声过程,因而具有零均值,同方差的特性 ...

  10. Java源代码编译过程

      编译其本质是将一种语言规范转换成另一种语言规范,即将Java语言规范转换为JVM虚拟机语言规范.结果就是.java文件到.class文件. 对于C/C++编译直接将高级语言转换为机器语言,Java ...