当前位置: 首页 > news >正文

做网站的公司哪个好万网手机网站

做网站的公司哪个好,万网手机网站,品牌建设部门工作职责与分工,中国建筑网登录入口代理模式#xff08;Proxy Pattern#xff09;是一种结构型设计模式#xff0c;它提供了对象的替身#xff0c;即代理对象来控制对实际对象的访问。通过代理对象#xff0c;可以在不修改目标对象的情况下#xff0c;扩展或控制其功能。例如#xff0c;代理模式可以用于延… 代理模式Proxy Pattern是一种结构型设计模式它提供了对象的替身即代理对象来控制对实际对象的访问。通过代理对象可以在不修改目标对象的情况下扩展或控制其功能。例如代理模式可以用于延迟加载、权限控制、日志记录等场景。 核心要点 代理对象代理模式通过代理对象替代实际对象进行控制代理对象和实际对象实现相同的接口。控制访问代理对象可以控制客户端与实际对象的交互甚至对客户端的请求进行预处理或后处理。延迟初始化代理对象可以在需要的时候才创建实际对象节省资源。 UML类图 Subject这是接口定义了代理对象和实际对象都要实现的公共接口包含方法 request()。 RealSubject实现 Subject 接口的类表示真正执行操作的对象。 Proxy同样实现了 Subject 接口代理 RealSubject 对象控制对 RealSubject 的访问 静态代理 静态代理是指在编译期就已经确定了代理类。我们必须手动创建代理类并明确代理哪个对象。代理类与被代理类实现相同的接口通过代理类来控制对实际对象的访问。 静态代理案例银行账户管理 假设我们有一个银行账户管理系统用户通过 BankAccount 类管理账户余额BankAccountProxy 作为代理类添加了权限控制功能只有拥有特定权限的用户才能执行账户操作 。 案例场景 实际对象BankAccount 负责执行账户的具体操作如查询余额。代理对象BankAccountProxy 负责控制对 BankAccount 的访问确保只有权限用户可以操作账户。 静态代理代码实现 Step 1: 定义接口 // Subject 接口 public interface BankAccount {void deposit(double amount);void withdraw(double amount);double getBalance(); } Step 2: 实现具体的银行账户类 // RealSubject 实现类 public class RealBankAccount implements BankAccount {private double balance;public RealBankAccount(double initialBalance) {this.balance initialBalance;}Overridepublic void deposit(double amount) {balance amount;System.out.println(Deposited amount , new balance is balance);}Overridepublic void withdraw(double amount) {if (amount balance) {balance - amount;System.out.println(Withdrew amount , new balance is balance);} else {System.out.println(Insufficient funds.);}}Overridepublic double getBalance() {return balance;} } Step 3: 实现代理类 // Proxy 类 public class BankAccountProxy implements BankAccount {private RealBankAccount realBankAccount;private String userRole;public BankAccountProxy(RealBankAccount realBankAccount, String userRole) {this.realBankAccount realBankAccount;this.userRole userRole;}Overridepublic void deposit(double amount) {if (userRole.equals(Admin)) {realBankAccount.deposit(amount);} else {System.out.println(Access denied: You dont have permission to deposit.);}}Overridepublic void withdraw(double amount) {if (userRole.equals(Admin)) {realBankAccount.withdraw(amount);} else {System.out.println(Access denied: You dont have permission to withdraw.);}}Overridepublic double getBalance() {return realBankAccount.getBalance();} } Step 4: 测试代理类 public class Client {public static void main(String[] args) {// 创建真实对象和代理对象RealBankAccount realAccount new RealBankAccount(1000);BankAccount proxyAccount new BankAccountProxy(realAccount, User);// 测试代理访问proxyAccount.deposit(500); // 访问受限proxyAccount.withdraw(300); // 访问受限// 以 Admin 身份访问BankAccount adminAccount new BankAccountProxy(realAccount, Admin);adminAccount.deposit(500); // 成功存款adminAccount.withdraw(300); // 成功取款} } 输出结果 Access denied: You dont have permission to deposit. Access denied: You dont have permission to withdraw. Deposited 500.0, new balance is 1500.0 Withdrew 300.0, new balance is 1200.0解释 权限控制BankAccountProxy 控制了对 RealBankAccount 的访问只有拥有 Admin 权限的用户才能操作账户。灵活扩展通过代理类我们可以在不修改 RealBankAccount 的前提下灵活地添加权限控制功能。 动态代理JDK 动态代理 动态代理是在运行时动态生成代理类而不是在编译时确定。动态代理可以通过反射机制自动生成代理对象而无需手动编写代理类。 动态代理案例银行账户管理JDK 动态代理 在 动态代理 中代理类是在运行时动态生成的。Java 提供了 java.lang.reflect.Proxy 类和 InvocationHandler 接口来实现动态代理。 案例场景 和静态代理案例类似我们还是使用 BankAccount 管理账户但是通过 JDK 动态代理 来动态生成代理类代理类控制用户的操作权限并记录日志 。 动态代理代码实现 Step 1: 定义接口与静态代理相同 // Subject 接口 public interface BankAccount {void deposit(double amount);void withdraw(double amount);double getBalance(); }Step 2: 实现具体的银行账户类与静态代理相同 // RealSubject 实现类 public class RealBankAccount implements BankAccount {private double balance;public RealBankAccount(double initialBalance) {this.balance initialBalance;}Overridepublic void deposit(double amount) {balance amount;System.out.println(Deposited amount , new balance is balance);}Overridepublic void withdraw(double amount) {if (amount balance) {balance - amount;System.out.println(Withdrew amount , new balance is balance);} else {System.out.println(Insufficient funds.);}}Overridepublic double getBalance() {return balance;} } Step 3: 实现 InvocationHandler 接口 InvocationHandler 是动态代理的核心通过 invoke() 方法拦截对目标对象的方法调用。 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method;public class BankAccountInvocationHandler implements InvocationHandler {private Object target;private String userRole;public BankAccountInvocationHandler(Object target, String userRole) {this.target target;this.userRole userRole;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {if (userRole.equals(Admin)) {System.out.println(Admin access granted.);return method.invoke(target, args); // 调用目标对象的方法} else {System.out.println(Access denied: You dont have permission to method.getName());return null;}} } Step 4: 动态代理测试 import java.lang.reflect.Proxy;public class Client {public static void main(String[] args) {// 创建真实对象RealBankAccount realAccount new RealBankAccount(1000);// 创建动态代理对象BankAccount proxyAccount (BankAccount) Proxy.newProxyInstance(realAccount.getClass().getClassLoader(),new Class[]{BankAccount.class},new BankAccountInvocationHandler(realAccount, User));// 测试代理访问proxyAccount.deposit(500); // 访问受限proxyAccount.withdraw(300); // 访问受限// 以 Admin 身份访问BankAccount adminAccount (BankAccount) Proxy.newProxyInstance(realAccount.getClass().getClassLoader(),new Class[]{BankAccount.class},new BankAccountInvocationHandler(realAccount, Admin));adminAccount.deposit(500); // 成功存款adminAccount.withdraw(300); // 成功取款} } 输出结果 Access denied: You dont have permission to deposit Access denied: You dont have permission to withdraw Admin access granted. Deposited 500.0, new balance is 1500.0 Admin access granted. Withdrew 300.0, new balance is 1200.0 解释 运行时生成代理类通过 Proxy.newProxyInstance() 方法动态生成代理类。权限控制动态代理可以在运行时灵活地进行权限控制且不需要手动创建代理类。 CGLIB 动态代理 通过生成目标类的子类并重写其中的方法来实现代理。它是在运行时生成的字节码所以可以代理普通类和接口。代理类实际上是目标类的子类并且会调用父类的方法。 依赖需要导入 cglib 相关的库。限制由于 CGLIB 是通过继承实现的所以不能代理 final 类或**final 方法**因为这些无法被继承和重写。 CGLIB 依赖导入 在项目中你需要下载CGLIB相关的所有JAR包或者使用 Maven 或 Gradle 导入 cglib 依赖 Jar包下载地址相关JAR点击下载 Maven 依赖 dependencygroupIdcglib/groupIdartifactIdcglib/artifactIdversion3.3.0/version /dependency Gradle 依赖 implementation cglib:cglib:3.3.0案例场景银行账户管理CGLIB 动态代理 我们将基于前面的银行账户管理系统使用 CGLIB 实现动态代理控制用户操作权限并记录日志 。 场景 实际对象BankAccount 是一个普通类没有实现任何接口。代理对象使用 CGLIB 动态生成代理类实现权限控制和日志功能 CGLIB 动态代理代码实现 Step 1: 创建 BankAccount 类 不再实现接口这是一个普通类CGLIB 可以代理这个类。 // RealSubject 实现类普通类没有实现接口 public class BankAccount {private double balance;public BankAccount(double initialBalance) {this.balance initialBalance;}public void deposit(double amount) {balance amount;System.out.println(Deposited amount , new balance is balance);}public void withdraw(double amount) {if (amount balance) {balance - amount;System.out.println(Withdrew amount , new balance is balance);} else {System.out.println(Insufficient funds.);}}public double getBalance() {return balance;} } Step 2: 创建 MethodInterceptor 实现类 MethodInterceptor 是 CGLIB 代理的核心通过重写 intercept() 方法来拦截目标类的方法调用 import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;public class BankAccountMethodInterceptor implements MethodInterceptor {private String userRole;public BankAccountMethodInterceptor(String userRole) {this.userRole userRole;}Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {if (userRole.equals(Admin)) {System.out.println(Admin access granted.);return proxy.invokeSuper(obj, args); // 调用父类的原方法} else {System.out.println(Access denied: You dont have permission to method.getName());return null;}} } Step 3: 使用 Enhancer 动态生成代理类 CGLIB 使用 Enhancer 类来生成代理对象Enhancer 会生成一个目标类的子类并将方法调用委托给 MethodInterceptor。 import net.sf.cglib.proxy.Enhancer;public class Client {public static void main(String[] args) {// 创建 Enhancer 对象Enhancer enhancer new Enhancer();enhancer.setSuperclass(BankAccount.class); // 设置代理目标类enhancer.setCallback(new BankAccountMethodInterceptor(User)); // 设置拦截器// 创建代理对象BankAccount proxyAccount (BankAccount) enhancer.create(new Class[]{double.class}, new Object[]{1000.0});// 测试代理访问proxyAccount.deposit(500); // 访问受限proxyAccount.withdraw(300); // 访问受限// 以 Admin 身份访问enhancer.setCallback(new BankAccountMethodInterceptor(Admin));BankAccount adminAccount (BankAccount) enhancer.create(new Class[]{double.class}, new Object[]{1000.0});adminAccount.deposit(500); // 成功存款adminAccount.withdraw(300); // 成功取款} } 输出结果 Access denied: You dont have permission to deposit Access denied: You dont have permission to withdraw Admin access granted. Deposited 500.0, new balance is 1500.0 Admin access granted. Withdrew 300.0, new balance is 1200.0 解释 动态生成代理类通过 Enhancer 类动态生成了 BankAccount 类的代理对象。权限控制MethodInterceptor 控制了对目标方法的调用只有具有 Admin 权限的用户才能执行操作。日志功能代理类在执行目标方法前打印日志信息。 CGLIB 动态代理的优缺点 优点 支持无接口类的代理CGLIB 能够代理普通类不要求目标类必须实现接口这比 JDK 动态代理更灵活。性能高相比 JDK 动态代理CGLIB 生成的代理类性能更高尤其是在大量调用代理方法的场景下。透明性客户端无需修改代理类的生成是透明的。 缺点 不能代理 final 类和方法由于 CGLIB 代理是通过生成子类实现的因此无法代理 final 类和 final 方法。依赖第三方库CGLIB 是一个外部库增加了项目的依赖复杂度。 总结CGLIB 动态代理的特点 代理普通类CGLIB 允许代理没有实现接口的类这比 JDK 动态代理更加灵活。通过继承实现代理CGLIB 生成目标类的子类并重写目标方法来实现代理。应用场景广泛CGLIB 动态代理适用于需要代理普通类、且调用频繁的场景。 Spring AOP 代理机制 Spring AOPAspect-Oriented Programming面向切面编程是 Spring 框架中的核心特性之一它通过代理对象来对目标对象的方法进行拦截在方法执行前后加入额外的逻辑如日志记录、权限验证、事务管理等。 Spring AOP 中使用了两种代理机制 JDK 动态代理基于接口的代理CGLIB 动态代理基于子类的代理 使用的代理类型 JDK 动态代理当目标类实现了接口时Spring AOP 默认使用 JDK 动态代理来生成代理对象。CGLIB 动态代理当目标类没有实现接口时Spring AOP 会使用 CGLIB 来生成代理对象。 Spring AOP 如何选择代理机制 Spring 选择代理的规则 如果目标对象实现了接口Spring AOP 默认使用 JDK 动态代理。如果目标对象没有实现接口Spring AOP 使用 CGLIB 动态代理。可以强制使用 CGLIB即使目标对象实现了接口也可以通过配置来强制使用 CGLIB 代理。 Spring AOP 动态代理应用场景 Spring AOP 的代理机制广泛应用于以下场景 事务管理通过代理对象在方法执行时自动管理事务的开启和提交。日志记录在方法执行前后自动添加日志记录。权限控制通过代理对象控制用户是否有权限调用某些方法。缓存机制在方法执行前先检查缓存如果缓存中存在结果则直接返回否则执行目标方法并将结果存入缓存 三种代理类型的对比 下表详细对比了 静态代理、JDK 动态代理 和 CGLIB 动态代理 的不同点。 对比维度静态代理JDK 动态代理CGLIB 动态代理实现方式手动创建代理类通过 Proxy 类和 InvocationHandler 动态生成通过继承目标类使用字节码生成子类是否需要接口是需要代理类和目标类实现相同接口是必须代理实现了接口的类否不需要接口直接代理类本身代理类生成时间编译时生成代码已确定运行时动态生成运行时动态生成实现复杂度需要手动编写代理类代码重复较简单自动生成代理类复杂度较高需要字节码生成库方法调用方式代理类直接调用目标类方法代理对象通过 InvocationHandler 反射调用目标方法通过字节码技术生成子类直接调用父类方法代理性能性能较好方法直接调用性能较差基于反射调用反射开销大性能较高生成的子类直接调用父类方法代理对象结构代理对象和目标对象有相同的接口代理对象和目标对象实现相同接口代理对象是目标类的子类应用场景适用于代理数量少、简单的场景适用于需要代理实现接口的场景适用于没有实现接口的类或者需要大量代理的场景是否可代理 final 类是否无法代理 final 类否无法代理 final 类优点实现简单直观灵活可以代理接口易于扩展可代理普通类性能较高适用于没有接口的类缺点需要为每个目标类手动编写代理类代码冗余只能代理接口基于反射调用性能较低无法代理 final 类依赖外部库配置较复杂 总结三种代理的特点和适用场景 静态代理 特点代理类由开发者手动编写固定且已确定代码较多、可维护性较低。适用场景代理类少、功能固定的场景简单、容易实现。 JDK 动态代理 特点只能代理实现了接口的类通过反射调用目标方法代理类在运行时生成性能相对较低。适用场景目标对象实现了接口尤其是需要动态代理多个接口的场景如日志记录、权限控制等。 CGLIB 动态代理 特点不要求目标类必须实现接口使用字节码生成技术生成目标类的子类性能高于 JDK 动态代理但无法代理 final 类和 final 方法。适用场景目标类没有实现接口且代理调用频繁时使用尤其适合对普通类的代理
http://www.w-s-a.com/news/485732/

相关文章:

  • 视频制作素材网站wordpress mysql 被删
  • 静态网站 模板公司一般都用什么邮箱
  • 做网站效果图是用ps还是ai泰安人才网最新招聘信息2022年
  • 免费建站网站一级大录像不卡在线看网页郑州网站关键
  • 做网站 然后百度推广哈尔滨建筑网
  • 章丘营销型网站建设网站测评必须做
  • 营销者网站怎么把网站黑了
  • 律师事务所手机网站校园网站设计
  • 网站案例展示分类网站响应速度优化
  • 风景网站的制作网站ip地址查询域名
  • 怎样看网站是谁做的马鞍山什么房产网站做的好
  • 西安推荐企业网站制作平台软装设计方案ppt
  • 网站静态页模板专业网站设计开发公司
  • 手机免费在线搭建网站短网址生成防红
  • 天津网站设计网站制作如何新建wordpress
  • 山东省建设备案网站审批国际新闻最新消息10条简短
  • 成都市建设网扬尘监控网站短域名转换
  • 怎么做手机网站潍坊建设银行网站
  • 做网站分什么软件品牌设计培训
  • 太原网站设计排名设计本装修效果图
  • 网站个人中心模板石家庄网站系统开发
  • 优秀的电子商务网站教育公司网站建设文案
  • 网站开发市场成本网站链接推广工具
  • 猪八戒做网站排名常州seo博客
  • wordpress 网站遭篡改如何优化公司的网站
  • 汉中公司做网站网站建设的风格设置
  • 网站建议怎么写怎么做网页连接
  • 站长工具seo综合查询下载安装软件平台搭建包括哪几个方面
  • 做网站怎么存放视频支付功能网站建设
  • 庆阳手机网站设计兰州网站的优化