场景描述: 假设我们有一个实现类- 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);
}
}
分享到:
相关推荐
java提高-动态代理与静态代理.docx
其在Windows平台上的版本为curl-7.68.0-win64-mingw,这是一个专为Windows 64位系统优化的版本,包含了所有必要的库和可执行文件,使得用户无需编译即可直接使用。 首先,让我们深入了解curl的核心功能。curl的主要...
Nginx是一款高性能的HTTP和反向代理服务器,广泛应用于Web服务领域,以其高效、稳定、轻量级的特性赢得了广大用户的青睐。本资源包含了Nginx的两个不同格式的版本:nginx-1.21.6.zip和nginx-1.21.6.tar.gz,分别适用...
在Windows平台上使用Curl的静态库,开发者可以避免因系统缺失特定版本的动态链接库而引发的问题。静态库版本的libcurl在编译时会被整合进应用程序中,确保程序在任何装有Windows系统的机器上都能正常运行,无需考虑...
在静态代理中,我们需要创建一个代理类,这个代理类与原始类(被代理类)具有相同的接口,通过代理类调用实际对象的方法。代理类通常会增加一些额外的操作,如日志记录、权限检查等。静态代理的主要缺点是代码冗余,...
Nginx 可以作为静态资源服务器,也可以配合其他应用服务器(如 PHP-FPM 或 Java 应用服务器)作为反向代理,实现动态内容的处理。在运维过程中,监控 Nginx 的状态和日志,以及定期更新到最新稳定版本,都是保持系统...
这个组合通常用于在 Windows 环境下搭建一个包含数据存储和动态内容分发的服务器环境。 Redis-x64-win-3.2.100.zip 文件包含了 Redis 的 Windows 64 位版本。Redis 在 Windows 上的安装和配置可能会与 Linux 等其他...
主要对Spring AOP的相关概念和简单的静态代理、动态代理以及常见的几种AOP配置方式做总结学习。主要包括:1. AOP的常见概念 2. 静态代理 3. jdk动态代理 4. Aspectj and Aspectjweaver 5. **aop-config** 6. CGLIB ...
OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 应用开发平台,它集成了 LuaJIT,并且提供了大量的库模块,使得开发者能够利用 Lua 脚本语言快速构建出高性能的动态 web 应用。在 `openresty-1.21.4.1-win64.zip` ...
Java中的代理模式--静态代理和动态代理 Java中的代理模式--静态代理和动态代理
ASM是一个强大的Java字节码操控和分析框架,它可以直接生成和修改Java类和注解的字节码。这个框架主要用于动态代理、代码分析以及优化等场景。在Java开发中,当我们需要在运行时生成或者修改类的行为时,ASM提供了一...
".tar.gz"是一个常见的Linux/Unix文件压缩格式,由tar进行归档,然后用gzip进行压缩,方便用户下载和在Linux环境中安装。 描述中提到的"搭建LNMP下nagios需要用到的插件",暗示了FCGI-ProcManager在LNMP(Linux + ...
Squid是一个广泛应用的开源代理服务器,其最新版本为3.5.28。在互联网访问控制、内容缓存和性能优化等方面,Squid扮演着至关重要的角色。本文将深入探讨Squid的基本概念、功能特性以及配置与管理方法。 一、Squid...
在Spring框架4.*版本中,可能会遇到一个常见问题,即缺少`spring-cglib-repack-3.2.5.jar`和`spring-objenesis-repack-2.6.jar`这两个jar文件。这两个文件是Spring框架运行时的重要依赖,它们涉及到Spring的动态代理...
Apache Tomcat是一个开源的应用服务器,主要用于运行Java Servlets和JavaServer Pages (JSP),而Nginx则是一个高性能的Web服务器和反向代理服务器,以其高效的处理静态内容和高并发能力而著名。 描述中提到,在...
LuaJIT是一个高效的Lua虚拟机实现,它不仅支持标准的Lua 5.1语法,还提供了Just-In-Time(JIT)编译技术,能够将Lua代码动态编译为机器码,显著提升执行效率。在标题中提到的"LuaJIT-2.0.4.tar.gz"是一个针对LuaJIT ...
为了更好地理解代理模式的工作原理,我们通过下面的例子来实现一个简单的代理模式。 **定义接口**: ```java public interface SellPerfume { void sellPerfume(double price); } ``` **定义真实对象**: ```java...
OpenResty的核心是Nginx,一个高性能的HTTP和反向代理服务器,以其出色的并发处理能力和低内存占用而闻名。通过OpenResty,我们可以将Nginx的功能扩展到动态内容生成、API处理、缓存控制等多个领域,同时保持Nginx的...
相比于静态代理,动态代理不需要为每个目标类创建单独的代理类,只需要一个通用的InvocationHandler实现。当需要代理某个对象时,我们可以创建一个InvocationHandler实例,然后使用Proxy.newProxyInstance()方法生成...