`
蓝色的墨
  • 浏览: 77709 次
  • 性别: Icon_minigender_1
  • 来自: 河南
社区版块
存档分类
最新评论

由一个小问题----静态代理---动态代理.

阅读更多

场景描述: 假设我们有一个实现类- userManager ,  这个实现类有很多方法(增删改查).现在需求发生了改变,当我们调用这个类里面的方法的时候,我们要检查一下,你有没有权利调用这些方法.

原接口:userManager

     package com.fd;

public interface UserManager {

public void addUser(String username ,String password);

   public void delUser(int userId);

   public String findUser(int userId);

   public void modifyUser(int userId , String username ,String password);

}

原接口实现:userManagerImpl

   package com.fd;

public class UserManagerImpl implements UserManager {

   public void addUser(String username, String password) {

     System.out.println("addUser");

   }

   public void delUser(int userId) {

     System.out.println("delUser");

   }

   public String findUser(int userId) {

     System.out.println("findUser");

     return "张三";

   }

   public void modifyUser(int userId, String username, String password) {

     System.out.println("modifyUser");

   }

}

现在需求变化,要在调用每一个方法之前,你都要检查一下是否有权限调用这些个方法.

原接口不变

原来的实现类要改变,当然我们不希望改变,我们都知道设计程序的一些原则:”对扩展开放,对修改关闭”.

那么由于需求的变化,我们现在的实现类要修改.(假如实现类中有很多方法的话,那就更痛苦了.)

package com.fd;

public class UserManagerImpl implements UserManager {

   public void addUser(String username, String password) {

     checkSecurity();

     System.out.println("addUser");

   }

   public void delUser(int userId) {

     checkSecurity();

     System.out.println("delUser");

   }

   public String findUser(int userId) {

     checkSecurity();

     System.out.println("findUser");

     return "张三";

   }

   public void modifyUser(int userId, String username, String password) {

     checkSecurity();

     System.out.println("modifyUser");

   }

  

    public void checkSecurity(){

      System.out.println("----------checkSecurity-----------");

    }

}

我们在其中加了一个权限检查的方法,而且,在实现类里面的每个方法里面都调用了一次.太麻烦了.而且容易出问题.

那现在我们使用静态代理. 保持原来的实现类不变.多加一个类,同样实现接口UserManager.再加上权限检查的方法.加上一个UserManager的引用.这样让它在执行的时候,去调用这个代理类,如果它有这个权限的话,再让它去调用真正实现类的方法.代码如下.

package com.fd;

public class UserManagerImplProxy implements UserManager {

   private UserManager userManager;

   public void addUser(String username, String password) {

     checkSecurity();

     userManager.addUser(username, password);

   }

   public void delUser(int userId) {

     checkSecurity();

     userManager.delUser(userId);

   }

 

   public String findUser(int userId) {

     checkSecurity();

     return userManager.findUser(userId);

   }

   public void modifyUser(int userId, String username, String password) {

     checkSecurity();

     userManager.modifyUser(userId, username, password);

   }

   public void checkSecurity() {

     System.out.println("----------checkSecurity-----------");

   }

}

这样一来,好处就是,原来的程序保持不变,仅仅扩展了一个类.就算出了问题,也好定位.但是,在调用它的方法之前,同样都要先调用同一个方法,就像一个独立的服务.我们可以单独的把它剥离出来.什么时候想加,就加上,想去掉,很轻松的就去掉了.那就看看我们的动态代理.面向接口编程.让目标和代理共同实现一个接口.

动态代理类SecurityHandler

package com.fd;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

public class SecurityHandler implements InvocationHandler {

   private Object targetObject;

   public Object createProxyInstance(Object targetObject) {

     this.targetObject = targetObject;

     return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),

          targetObject.getClass().getInterfaces(), this);

 

   }

   @Override

   public Object invoke(Object proxy, Method method, Object[] args)

        throws Throwable {

     checkSecurity() ;

     Object ret = method.invoke(targetObject, args);

 

     return ret;

   }

 

   public void checkSecurity() {

     System.out.println("----------checkSecurity-----------");

   }

 

}

 

客户端代码

package com.fd;

public class Client {

   public static void main(String[] args){

     SecurityHandler handler = new SecurityHandler();

     UserManager userManager = (UserManager)handler.createProxyInstance(new UserManagerImpl());

     userManager.addUser("张三", "123");

     userManager.delUser(1);

     userManager.findUser(2);

     

   }

}

0
0
分享到:
评论

相关推荐

    java提高-动态代理与静态代理.docx

    java提高-动态代理与静态代理.docx

    curl-7.68.0-win64-mingw.zip

    其在Windows平台上的版本为curl-7.68.0-win64-mingw,这是一个专为Windows 64位系统优化的版本,包含了所有必要的库和可执行文件,使得用户无需编译即可直接使用。 首先,让我们深入了解curl的核心功能。curl的主要...

    nginx-1.21.6.zip和nginx-1.21.6.tar.gz

    Nginx是一款高性能的HTTP和反向代理服务器,广泛应用于Web服务领域,以其高效、稳定、轻量级的特性赢得了广大用户的青睐。本资源包含了Nginx的两个不同格式的版本:nginx-1.21.6.zip和nginx-1.21.6.tar.gz,分别适用...

    curl-7.85.0 Windows平台静态库

    在Windows平台上使用Curl的静态库,开发者可以避免因系统缺失特定版本的动态链接库而引发的问题。静态库版本的libcurl在编译时会被整合进应用程序中,确保程序在任何装有Windows系统的机器上都能正常运行,无需考虑...

    代理模式-静态动态代理-jdk动态代理-cglib动态代理

    在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)具有相同的接口,通过代理类调用实际对象的方法。代理类通常会增加一些额外的操作,如日志记录、权限检查等。静态代理的主要缺点是代码冗余,...

    nginx-1.18.0-1.el7.ngx.x86_64

    Nginx 可以作为静态资源服务器,也可以配合其他应用服务器(如 PHP-FPM 或 Java 应用服务器)作为反向代理,实现动态内容的处理。在运维过程中,监控 Nginx 的状态和日志,以及定期更新到最新稳定版本,都是保持系统...

    Redis-x64-win-3.2.100+nginx-win

    这个组合通常用于在 Windows 环境下搭建一个包含数据存储和动态内容分发的服务器环境。 Redis-x64-win-3.2.100.zip 文件包含了 Redis 的 Windows 64 位版本。Redis 在 Windows 上的安装和配置可能会与 Linux 等其他...

    Spring aop 之 静态代理 动态代理 Aspectj aop-config 等实现方式

    主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...

    openresty-1.21.4.1-win64.zip 包下载

    OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 应用开发平台,它集成了 LuaJIT,并且提供了大量的库模块,使得开发者能够利用 Lua 脚本语言快速构建出高性能的动态 web 应用。在 `openresty-1.21.4.1-win64.zip` ...

    Java中的代理模式--静态代理和动态代理

    Java中的代理模式--静态代理和动态代理 Java中的代理模式--静态代理和动态代理

    asm-2.2.3.jar,asm-commons-2.2.3.jar,asm-util-2.2.3.jar

    ASM是一个强大的Java字节码操控和分析框架,它可以直接生成和修改Java类和注解的字节码。这个框架主要用于动态代理、代码分析以及优化等场景。在Java开发中,当我们需要在运行时生成或者修改类的行为时,ASM提供了一...

    FCGI-ProcManager-0.18.tar.gz

    ".tar.gz"是一个常见的Linux/Unix文件压缩格式,由tar进行归档,然后用gzip进行压缩,方便用户下载和在Linux环境中安装。 描述中提到的"搭建LNMP下nagios需要用到的插件",暗示了FCGI-ProcManager在LNMP(Linux + ...

    squid-3.5.28.tar.gz

    Squid是一个广泛应用的开源代理服务器,其最新版本为3.5.28。在互联网访问控制、内容缓存和性能优化等方面,Squid扮演着至关重要的角色。本文将深入探讨Squid的基本概念、功能特性以及配置与管理方法。 一、Squid...

    spring 4.* 缺少jar spring-cglib-repack-3.2.5.jar_spring-objenesis-repack-2.6.jar

    在Spring框架4.*版本中,可能会遇到一个常见问题,即缺少`spring-cglib-repack-3.2.5.jar`和`spring-objenesis-repack-2.6.jar`这两个jar文件。这两个文件是Spring框架运行时的重要依赖,它们涉及到Spring的动态代理...

    apache-tomcat-7.0.52.tar.gz+nginx-1.8.0.tar.gz

    Apache Tomcat是一个开源的应用服务器,主要用于运行Java Servlets和JavaServer Pages (JSP),而Nginx则是一个高性能的Web服务器和反向代理服务器,以其高效的处理静态内容和高并发能力而著名。 描述中提到,在...

    LuaJIT-2.0.4.tar.gz

    LuaJIT是一个高效的Lua虚拟机实现,它不仅支持标准的Lua 5.1语法,还提供了Just-In-Time(JIT)编译技术,能够将Lua代码动态编译为机器码,显著提升执行效率。在标题中提到的"LuaJIT-2.0.4.tar.gz"是一个针对LuaJIT ...

    Java 代理 代理模式 静态代理与动态代理 常见的动态代理实现 .md

    为了更好地理解代理模式的工作原理,我们通过下面的例子来实现一个简单的代理模式。 **定义接口**: ```java public interface SellPerfume { void sellPerfume(double price); } ``` **定义真实对象**: ```java...

    openresty-1.19.3.1-win64.zip

    OpenResty的核心是Nginx,一个高性能的HTTP和反向代理服务器,以其出色的并发处理能力和低内存占用而闻名。通过OpenResty,我们可以将Nginx的功能扩展到动态内容生成、API处理、缓存控制等多个领域,同时保持Nginx的...

    Java静态代理和动态代理

    相比于静态代理,动态代理不需要为每个目标类创建单独的代理类,只需要一个通用的InvocationHandler实现。当需要代理某个对象时,我们可以创建一个InvocationHandler实例,然后使用Proxy.newProxyInstance()方法生成...

Global site tag (gtag.js) - Google Analytics