如何简单描述java中的代理模式
java里什么是代理
比如A是一个接口,B是被加强对象,C是代理对象
A接口有一个say()方法,B实现了A接口,C也实现了A接口,C在自己实现的say()方法里不但执行了B的say()方法也执行了一些自己的程序,这就是代理。
代理分为静态代理和动态代理。
为什么要代理
类的增强可以通过继承来实现,那如果想让某个方法增强呢?这时候就用到代理了。
如何代理?
大体上有目标类,代理类,增强(通知),连接点。
代理类在连接点处通过增强(通知)来对目标类进行增强。
我简单理解成增强就是在目标执行某方法进行拦截时执行的代码,拦截就是对方法或者参数进行分析,具体拦截后怎么做自己想怎么写就怎么写。
连接点是指那些被拦截到的点,大白话就是在哪些方法中拦截,总不能所有目标类的方法都拦截吧,只拦截我想要增强的方法就行了,在Spring中这些点指的是方法因为Spring只支持方法类型的连接点
静态代理的用途
控制真实对象的访问权限 通过代理对象控制对真实对象的使用权限。
避免创建大对象 通过使用一个代理小对象来代表一个真实的大对象,可以减少系统资源的消耗,对系统进行优化并提高运行速度。
增强真实对象的功能 这个比较简单,通过代理可以在调用真实对象的方法的前后增加额外功能。
代理分为静态代理和动态代理
静态代理:
1、代理对象和目标对象都要实现的 公共接口
2、代理对象持有目标对象引用,重写构造方法,
3、实现共同的方法,代理对象增强行为。
缺点:
代理角色固定,一次只能代理一个对象。
接口
public interface Marry { void marry(); }
目标对象
public class You implements Marry { public void marry() { System.out.println("sihai get marry"); } }
代理对象
public class MarryCompany implements Marry { private You you; public MarryCompany(You you) { this.you = you; } public void marry() { before(); you.marry(); after(); } private void after() { System.out.println("get after work done"); } private void before() { System.out.println("get ready for marry"); } }
测试
public class TestMarry { public static void main(String[] args) { You you = new You(); MarryCompany marryCompany = new MarryCompany(you); marryCompany.marry(); } }
结果
get ready for marry sihai get marry get after work done
动态代理
问题1.不能手动的为每一个目标都写代理。
那么多目标,一个一个写是不是太浪费时间了?
这时有两种解决方案:
(1)JDK的动态---运行过程代理,启动快执行慢,首选,必须接口实现,JDK动态代理的过程中,生成的动态代理对象与目标对象是同一接口实现
(2)CGLIB的动态代理---从字节级别代理,启动比JDK费时间但执行快,会为每一个目标类生成对应的子类
问题2.对于增强,不能写成硬编码
硬编码是说写死的编码,增强的方法都写死固然会很繁琐
JDK的动态代理
实现JDK的动态代理有两部分最重要:
1.动态代理对象的生成(需要类加载器,实现接口类型,调用处理程序,源码这样写的)
2.调用处理程序(执行的增强方法)
举个栗子:
接口类
public interface DogI {void say();
}
目标类
public class Dog implements DogI{@Overridepublic void say() {System.out.println("hello");}}
动态生成代理对象的类
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;public class DogJDKPROXY implements InvocationHandler {//target为传进来的目标类private Object target;//获取传进来的目标类,并获取目标类的 类加载器,类接口,this指的是调用此方法的目标(还是目标类),需要实现InvocationHandler接口,重写invoke方法并执行public Object getProxyObject(Object target) {this.target=target;return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);}//在这里可以进行拦截,加强之类的操作,我这里什么增强都没写@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//代理的类,执行的方法,传递的参数Object result = method.invoke(target, args);return result;}
}
测试
public class Test {public static void main(String[] args) {DogI dog =(DogI) new DogJDKPROXY().getProxyObject(new Dog());dog.say();}
}
JDK的动态代理是生成 目标类 的 接口对象 ,是接口对象!
CGLIB的动态代理
目标类
public class Person {public void say() {System.out.println("hello");}
}
动态生成代理对象的类
import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;public class PersonCGLIBProxy implements MethodInterceptor{//target为传过来的目标类private Object target;//获取目标类,需要Enhancer对象获取目标类的,然后从字节码的级别创造代理对象,设置setCallback才能拦截(增强),把目标类放进去实现MethodInterceptor并重写interceptpublic Object getProxyObject(Object target) {this.target=target;Enhancer enhancer=new Enhancer();enhancer.setSuperclass(target.getClass());enhancer.setCallback(this);return enhancer.create();}//这个方法就是增强的地方,arg0为生成的代理对象,arg1传进来的需要增强的方法(这里默认目标类的方法都拦截了)@Overridepublic Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy methodProxy) throws Throwable {Object result=methodProxy.invoke(target, arg2);return result;}
}
测试
public class Test {public static void main(String[] args) {Person p = (Person) new PersonCGLIBProxy().getProxyObject(new Person());p.say();}
}
对比一下两者发现非常相似,都是传过来一个目标类,然后获取这个目标类的某些东西,然后创建一个代理类,如果代理类执行方法,就会通过一个固定的方法来获取这个方法以及这个方法的参数,然后在代理类的这个方法里进行一些处理。
但是:使用动态代理机制虽然解决了代理对象的生成问题,但是要为对象的哪个方法增强,以及增强应该如何实现等等,没有实现这样的功能,所以非常不灵活
为了解决这个方法,可以使用Spring的AOP解决。
动态代理的用途
Java的动态代理,在日常开发中可能并不经常使用,但是并不代表他不重要。Java的动态代理的最主要的用途就是应用在各种框架中。因为使用动态代理可以很方便的运行期生成代理类,通过代理类可以做很多事情,比如AOP,比如过滤器、拦截器等。
在我们平时使用的框架中,像servlet的filter、包括spring提供的aop以及struts2的拦截器都使用了动态代理功能。我们日常看到的mybatis分页插件,以及日志拦截、事务拦截、权限拦截这些几乎全部由动态代理的身影。
总结:
如何简单描述java中的代理模式相关推荐
- 轻松学,Java 中的代理模式(proxy)及动态代理
我们先来分析代理这个词. 代理 代理是英文 Proxy 翻译过来的.我们在生活中见到过的代理,大概最常见的就是朋友圈中卖面膜的同学了. 她们从厂家拿货,然后在朋友圈中宣传,然后卖给熟人. 按理说,顾客 ...
- 轻松学,Java 中的代理模式及动态代理
前几天我写了<秒懂,Java 注解 (Annotation)你可以这样学>,因为注解其实算反射技术中的一部分,然后我想了一下,反射技术中还有个常见的概念就是动态代理,于是索性再写一篇关于动 ...
- JAVA面试要点006---.net中的委托与java中的代理模式和委托
1.1.1 定义 委托是一种引用方法的类型.一旦为委托分配了方法,委托将与该方法具有完全相同的行为.委托方法的使用可以像其他任何方法一样,具有参数和返回值,如下面的示例所示: //Code in C# ...
- Java中的代理模式
1.什么是代理模式 代理模式:就是为其他对象提供一种代理以控制对这个对象的访问. 代理可以在不改动目标对象的基础上,增加其他额外的功能(扩展功能). 举个例子来说明代理的作用: 一般我们想邀请明星来当 ...
- 模式代码 java中aes_深入浅出:Java中的代理模式
代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象,用来在系统中对原始的接口进行替换,然后在内部做一些增强处理.代理模式不会破坏系统的原有接口,不去修改原有的 ...
- Java中动态代理的两种方式JDK动态代理和cglib动态代理以及区别
视频功能审核通过了,可以看视频啦!记得点关注啊~ 注意:因为网络原因,视频前一两分钟可能会比较模糊,过一会儿就好了 记得点关注啊,视频里的wx二维码失效了,wx搜索:"聊5毛钱的java&q ...
- Spring中的代理模式
Spring中的代理模式,是Spring中一大核心 AOP(切面编程)的底层实现. 代理模式可分为: 静态代理 动态代理 静态代理 涉及三类角色,简单分析一下: 抽象角色(一般会使用接口或抽象类解决) ...
- Android中的代理模式
Android中的代理模式 1. 什么是代理 比如我们生活中的找出租屋,需要去找中介进行寻找挑选.而这里的中介就是代理.列子中看出代理特点如下1. 租客跟中介要做成的最终目的是一致的就是租到房子(目标 ...
- Java 设计模式_代理模式(2016-08-19)
概念: 代理模式是对象的结构模式.代理模式给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用. 就是一个人或者机构代表另一个人或者机构采取行动.在一些情况下,一个客户不想或者不能够直接引用一 ...
- Java中的贷款模式(又名贷方承租人模式)
这篇文章是关于在Java中实现贷款模式的. 用例 在保存资源的代码与访问资源的代码之间实现分离,从而使访问代码无需管理资源. 当我们编写用于读取/写入文件或查询SQL / NOSQL数据库的代码时,上 ...
最新文章
- python统计字符串汉字个数_Python使用递归计算字符串中的字符数
- Crypto API
- Linux下配置rdate时间服务器
- 怎样用命令行生成自己的签名文件keystore
- 2020\Simulation_2\4.括号序列
- 网狐动态数组CWHArray
- Eclipse创建java webproject配置Tomacat和JDK
- 在斯坦福,做 Manning 的 phd 要有多强?
- Android 系统(164)---手机收到8bit编码的短信无法显示
- 客户和服务器之间响应的序列,Redis的请求/响应协议和往返时间详解
- 201521123059 《Java程序设计》第三周学习总结
- [CTSC2018]假面(概率DP)
- unity Scene窗口的任意比例放大和缩小
- HTTP 长连接 使用场景
- 知了课堂 python_知了传课 - 主页
- 测试开发工程师简历模版
- 如何一个月左右拿下PAT甲级(浙大机试)满分
- JUnit5学习之一:基本操作
- matlab柱状图设置条纹,matlab代码画条纹柱状图
- VSCode小说神器Thief-Book-VSCode页数获取
热门文章
- 如何让sublime编译c语言,如何在Sublime Text 3中编译C程序?
- 单片机C语言控制16*16LED显示屏,基于单片机的pwm控制16*16led点阵亮度调节怎么做啊,...
- 自动驾驶 11-2: 激光雷达传感器模型和点云 LIDAR Sensor Models and Point Clouds
- 2012年之前Mac Book pro 安装新系统macOS 10.15 Catalina 制作U盘启动盘
- 写jsx_使用Vue 3.0做JSX(TSX)风格的组件开发
- ad如何计算电路板的pin数量_PCB厂一到八层电路板的叠层设计方式
- DSSM核心思想是把查询文本(query)和内容文本(doc)映射到同维度的语义空间中, 以最优化查询文本和内容文本的语义向量之间的余弦相似度为目的
- 215.数组中的第K个最大元素
- 创建一个超链接,点击这个超链接,显示数据库中的数据信息:MVC模式查询
- 最大熵模的理解与最大熵模型逻辑回归相似转换条件