Spring原理之代理与动态代理模式总结(四)

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

代理模式

  • 1,什么是代理模式?
    代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问。

  • 2,代理模式有什么好处?
    在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。

  • 3,代理模式一般涉及到的角色有:

    • 抽象角色:声明真实对象代理对象共同接口,这样一来在任何可以使用目标对象的地方都可以使用代理对象
    • 代理角色:代理对象内部含有目标对象的引用,从而可以在任何时候操作目标对象;代理对象提供一个与目标对象相同的接口,以便可以在任何时候替代目标对象。代理对象通常在客户端调用传递给目标对象之前或之后,执行某个操作,而不是单纯地将调用传递给目标对象,同时,代理对象可以在执行真实对象操作时,附加其他的操作,相当于对真实对象进行封装。
    • 真实角色:定义了代理对象所代表的目标对象,代理角色所代表的真实对象,是我们最终要引用的对象,定义了代理对象所代表的目标对象。
public abstract class AbstractObject {//操作public abstract void operation();
}
public class RealObject extends AbstractObject {@Overridepublic void operation() {//一些操作System.out.println("一些操作");}
}
public class ProxyObject extends AbstractObject{RealObject realObject = new RealObject();@Overridepublic void operation() {//调用目标对象之前可以做相关操作System.out.println("before");        realObject.operation();        //调用目标对象之后可以做相关操作System.out.println("after");}
}
public class Client {public static void main(String[] args) {// TODO Auto-generated method stubAbstractObject obj = new ProxyObject();obj.operation();}
}
18173245_giRn.png
  • 案例二
public interface FontProvider {Font getFont(String name);
}
public abstract class ProviderFactory {public static FontProvider getFontProvider() {return new FontProviderFromDisk();}
}
public class Main() {public static void main(String[] args) {FontProvider fontProvider = ProviderFactory.getFontProvider();Font font = fontProvider.getFont("微软雅黑");......}
}
//现在我们希望给他加上一个缓存功能,我们可以用静态代理来完成
public class CachedFontProvider implements FontProvider {private FontProvider fontProvider;private Map<String, Font> cached;public CachedFontProvider(FontProvider fontProvider) {this.fontProvider = fontProvider;}public Font getFont(String name) {Font font = cached.get(name);if (font == null) {font = fontProvider.getFont(name);cached.put(name, font);}return font;}
}
/* 对工厂类进行相应修改,代码使用处不必进行任何修改。 这也是面向接口编程以及工厂模式的一个好处 */
public abstract class ProviderFactory {public static FontProvider getFontProvider() {return new CachedFontProvider(new FontProviderFromDisk());}
}
18173245_giRn.png
  • 案例三
考虑以下各种情况,有多个提供类,每个类都有getXxx(String name)方法,每个类都要加入缓存功能,使用静态代理虽然也能实现,但是也是略显繁琐,需要手动一一创建代理类。
public abstract class ProviderFactory {public static FontProvider getFontProvider() {...}public static ImageProvider getImageProvider() {...}public static MusicProvider getMusicProvider() {...}......
}
使用动态代理怎么完成呢?
public class CachedProviderHandler implements InvocationHandler {private Map<String, Object> cached = new HashMap<>();private Object target;public CachedProviderHandler(Object target) {this.target = target;}public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {Type[] types = method.getParameterTypes();if (method.getName().matches("get.+") && (types.length == 1) &&(types[0] == String.class)) {String key = (String) args[0];Object value = cached.get(key);if (value == null) {value = method.invoke(target, args);cached.put(key, value);}return value;}return method.invoke(target, args);}
}
public abstract class ProviderFactory {public static FontProvider getFontProvider() {Class<FontProvider> targetClass = FontProvider.class;return (FontProvider) Proxy.newProxyInstance(targetClass.getClassLoader(),new Class[] { targetClass },new CachedProviderHandler(new FontProviderFromDisk()));}
}
18173245_giRn.png

动态代理

  • 代理:本来应该自己做的事情,却请了别人来做,被请的人就是代理对象。
    • 举例:春季回家买票让人代买
  • 动态代理:在程序运行过程中产生的这个对象,此对象其实就是我们刚才反射讲解的内容,所以动态代理其实就是通过反射来生成一个代理

  • 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象。JDK提供的代理只能针对接口做代理。我们有更强大的代理cglib

  • Proxy类中的方法创建动态代理类对象

    • public static Object newProxyInstance(ClassLoader loader,Class
public class MyInvocationHandler implements InvocationHandler {private Object target; // 目标对象public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {System.out.println("权限校验");Object result = method.invoke(target, args);System.out.println("日志记录");return result; // 返回的是代理对象}
}
public interface StudentDao {public abstract void login();public abstract void regist();
}
public class StudentDaoImpl implements StudentDao {@Overridepublic void login() {System.out.println("登录功能");}@Overridepublic void regist() {System.out.println("注册功能");}
}
/* * 用户操作接口 */
public interface UserDao {public abstract void add();public abstract void delete();public abstract void update();public abstract void find();
}
public class UserDaoImpl implements UserDao {@Overridepublic void add() {System.out.println("添加功能");}@Overridepublic void delete() {System.out.println("删除功能");}@Overridepublic void update() {System.out.println("修改功能");}@Overridepublic void find() {System.out.println("查找功能");}
}
public class Test {public static void main(String[] args) {UserDao ud = new UserDaoImpl();ud.add();ud.delete();ud.update();ud.find();System.out.println("-----------");// 我们要创建一个动态代理对象// 我准备对ud对象做一个代理对象MyInvocationHandler handler = new MyInvocationHandler(ud);UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(), ud.getClass().getInterfaces(), handler);proxy.add();proxy.delete();proxy.update();proxy.find();System.out.println("-----------");StudentDao sd = new StudentDaoImpl();MyInvocationHandler handler2 = new MyInvocationHandler(sd);StudentDao proxy2 = (StudentDao) Proxy.newProxyInstance(sd.getClass().getClassLoader(), sd.getClass().getInterfaces(), handler2);proxy2.login();proxy2.regist();}
}
18173245_giRn.png



转载于:https://my.oschina.net/u/3676262/blog/1552877

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/280123.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

可执行文件添加快捷方式_如何停止Windows向快捷方式文件名添加“-快捷方式”...

可执行文件添加快捷方式When you make a new shortcut in Windows, it automatically adds “- Shortcut” to the end of the shortcut’s file name. This doesn’t seem like a big deal, but they can be bothersome. Sure, you can remove the text yourself when you cre…

看明星合影争C位,学PPT中C位排版法

在娱乐圈里&#xff0c;C位是大咖位&#xff0c;是对艺人实力的最好证明&#xff0c;艺人们自然会想着去力争C位&#xff0c;正所谓“不想当将军的兵不是好兵&#xff0c;不想站C位的明星不是好明星”。那么&#xff0c;C位是什么意思&#xff1f;C位&#xff0c;网络流行语&am…

javafx由浅到深的 认识(一)

javafx是一款比较新兴的语言框架,随着javafx越来越实用,估计许多程序员也会慢慢接触它,故我在这里对它由浅到深进行介绍一下. 首先,要了解javafx,就应该先知道.xml文件的布局软件,以往java都是通过敲代码来进行布局的,但javafx有力新的突破,它实现了拖动方式,目前我使用的辅助软…

linux用户的根目录_为什么Linux允许用户删除根目录?

linux用户的根目录Most of the time, none of us willingly performs an action that will literally break our operating systems and force us to reinstall them. But what if such an action could easily occur even by accident on the user’s part? Today’s SuperUs…

微软跨平台maui开发chatgpt客户端

image什么是maui.NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架&#xff0c;用于使用 C# 和 XAML 创建本机移动(ios,andriod)和桌面(windows,mac)应用。imagechagpt最近这玩意很火&#xff0c;由于网页版本限制了ip&#xff0c;还得必须开代理&#xff0c; 用起来比较麻烦&a…

在Xshell 6开NumLock时按小键盘上的数字键并不能输入数字

小键盘问题 在Xshell 6上用vi的时候&#xff0c;开NumLock时按小键盘上的数字键并不能输入数字&#xff0c;而是出现一个字母然后换行&#xff08;实际上是命令模式上对应上下左右的键&#xff09;。解决方法 选项Terminal->Features里&#xff0c;找到Disable application …

chrome 固定缩放比例_您如何调整Google Chrome浏览器的用户界面缩放比例?

chrome 固定缩放比例Everything can be going along nicely until a program gets a new update that suddenly turns everything into a visual mess, like scaling up the UI, for example. Is there a simple solution? Today’s SuperUser Q&A post has some helpful …

优雅告别 2022 年,2023 年主题:敢想,就敢做!

自从工作之后&#xff0c;每年春节我都会花一天时间&#xff0c;一个人待在一个小房间&#xff0c;思考自己今年做了什么具备阶段性成果的事情。然后&#xff0c;写下明年需要执行的计划。会写在一个 XMind 文件里&#xff0c;记录每一年将要执行的计划&#xff0c;且未完成的计…

java发送gmail_如何在Gmail中轻松通过电子邮件发送人群

java发送gmailMailing lists are an old tool in the email arsenal, but their implementation in Gmail isn’t immediately intuitive. Read on as we show you how to email groups using your Gmail account. 邮件列表是电子邮件库中的一个旧工具&#xff0c;但是在Gmail中…

Asp.net MVC使用Model Binding解除Session, Cookie等依赖

上篇文章"Asp.net MVC使用Filter解除Session, Cookie等依赖"介绍了如何使用Filter来解除对于Session, Cookie的依赖。其实这个也可以通过Model Binding来达到同样的效果。 什么是Model Binding? Model Binding的作用就是将Request请求中包含的散乱参数&#xff0c;根…

火狐 新增标签 一直加载_在Firefox的新标签页中加载最后标签页的URL

火狐 新增标签 一直加载Yeah, you’re pretty sure that you’re the master of all things Firefox. I mean, why else would you be reading this article? So, we’ve got to ask, have you ever seen this one before? 是的&#xff0c;您很确定自己是Firefox的所有人。 …

ptyhon【递归练习】

转载于:https://www.cnblogs.com/LTEF/p/9187287.html

JAVA常量

2019独角兽企业重金招聘Python工程师标准>>> 常量就是一个固定值。它们不需要计算&#xff0c;直接代表相应的值。 常量指不能改变的量。 在Java中用final标志&#xff0c;声明方式和变量类似&#xff1a; final double PI 3.1415927; 虽然常量名也可以用小写&…

基于Docker托管Azure DevOps代理

Azure DevOps非常好用&#xff0c;但是为代理准备单独的服务器经常会显得性价比不高&#xff1a;配置低了&#xff0c;前端构建时会教会你做人&#xff0c;配置太高又有点浪费资源&#xff0c;代理数量少了各团队构建要打架。对于既想享受DevOps的美妙之处但是资源捉襟见肘的小…

微软 word转换pdf_如何将行转换为Microsoft Word表中的列

微软 word转换pdfYou’ve created a table in Word and started to enter your data. Then, you realize that the table should be transposed, meaning the rows should be columns and vice versa. Rather than recreating the table and manually entering the data again,…

pycharm中如何正确配置pyqt5

网上看了几个文章&#xff0c;不成功。这样做才是正确姿势&#xff1a; /Users/mac/anaconda3/bin/Designer.app /Users/mac/anaconda3/bin$ProjectFileDir$ pyuic5 $FileName$ -o $FileNameWithoutExtension$.py $ProjectFileDir$ 其它细节懒得说。 转载于:https://www.cnblog…

如何在Photoshop中制作双曝光图像

Double exposure images are popular at the moment. Taylor Swift’s Style music video and the True Detective opening theme both used the effect. It’s a technique where two separate photos—typically a portrait and a landscape—are blended together into one …

记一次.NET 某安全生产系统 CPU爆高分析

一&#xff1a;背景 1.讲故事今天是&#x1f40f;的第四天&#xff0c;头终于不巨疼了&#xff0c;写文章已经没什么问题&#xff0c;赶紧爬起来写。这个月初有位朋友找到我&#xff0c;说他的程序出现了CPU爆高&#xff0c;让我帮忙看下怎么回事&#xff0c;简单分析了下有两点…

JDBC 学习笔记(一)—— JDBC 基础

1. 什么是 JDBC JDBC&#xff0c;Java Database Connectivity&#xff08;Java 数据库连接&#xff09;&#xff0c;是一组执行 SQL 语句的 Java API。 JDBC&#xff0c;是 Java SE&#xff08;Java Platform, Standard Edition&#xff09;标准的一部分。 Java 程序可以通过 J…

JavaScript享元模式

JavaScript享元模式 通过两个例子的对比来凸显享元模式的特点&#xff1a;享元模式是一个为了提高性能(空间复杂度)的设计模式&#xff0c;享元模式可以避免大量非常相似类的开销。 第一实例&#xff0c;没有使用享元模式&#xff0c;计算所花费的时间和空间使用程度。 要求为&…