Java中的代理
代理解释:一种设计模式,代理类与委托类(被代理对象、目标对象)有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
通俗解释:不直接调运目标对象,直接调运代理对象,让代理对象去调运目标对象。
代理目的:当调运代理对象,然后在代理对象调运目标对象之前或者调运目标对象以后,我们可以干一些事,比如权限控制,日志记录等。
代理分类:静态代理,动态代理
举例分析:
程序说明:有刚学说话的个小朋友想说“我是中国人”,但是他不能完整的说出来,只能说“中国”两个字,那么我们就使用代理模式,让他的爸爸妈妈帮他把他想说的话补充完整。他的爸爸帮他说:“我是”,他的妈妈帮他说:“人”。然后即使小朋友只说了“中国”,但是我们听见的就是“我是中国人”。
这其中小朋友就是被代理对象、目标对象,他的爸爸妈妈就是代理对象。
首先建立一个Person接口:
public interface Person { public void say(); }
建立一个接口的实现类:
public class PersonImpl implements Person { @Override public void say() { System.out.print("中国"); } }
再建立一个没有实现接口的类:
public class PersonNoImpl { public void say() { System.out.print("中华人民共和国"); } }
1.静态代理:在程序运行前,代理类的.class文件就已经存在了。
public class PersonProxy implements Person { private Person person;// 被代理对象 public PersonProxy(Person p) { this.person = p; } @Override public void say() { System.out.print("我是-"); person.say();// 在目标方法前后分别添加操作 System.out.println("-人"); } }
这种方式的最大缺点就是每次我们都需要建立不同的代理对象,灵活性和可复用性都很差,所以我们需要使用到动态代理技术。
2.动态代理:在程序运行时,运用反射机制动态创建而成。
有两种实现方式:JDK代理,CGLIB代理
方式1:使用jdk提供的代理对象(代理对象需要实现InvocationHandler接口,目标对象必须实现其他接口)
public class PersonProxyJdk implements InvocationHandler { private Object targetObj; /** * * @param obj * 被代理对象 * @return 代理对象的实例 */ public Object createProxyInstance(Object obj) { this.targetObj = obj; /* * 参数说明 参数一:ClassLoader,定义代理类的类加载器 * 参数二:Class<?>,代理类要实现的接口列表 * 参数三:InvocationHandler,指派方法调用的调用处理程序 (指定调运哪个类的invoke方法) */ return Proxy.newProxyInstance(obj.getClass().getClassLoader(), this.targetObj.getClass().getInterfaces(), this); } /* * 当代理对象的方法被调运时,就会执行回调函数invoke方法,让这个回调函数再去执行目标代码的指定方法, * 并且会将代理对象接收到的参数传递给目标代码。 这是一个回调函数。 * 注意:method args 都是由调运代理对象后产生的。所以是确定的。 * 还可以在这个回调函数中做一些手脚,比如限制调运或者其他。 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.print("我是*"); result = method.invoke(targetObj, args); System.out.println("*人"); return result; } }
注意:目标对象必须实现接口。因为需要得到接口的所有方法,然后进行调运接口的所有方法。
方式2:使用cglib提供的代理对象(代理对象需要实现MethodInterceptor接口,目标对象不需要实现接口)
//导包:cglib-nodep-2.2.3.jar public class PersonProxyCglib implements MethodInterceptor { private Object targetObj; /** * 生成的代理对象其实就是目标对象的子类 * @param obj * 被代理对象 * @return 代理对象的实例 */ public Object createProxyInstance(Object obj) { this.targetObj = obj; Enhancer enhancer = new Enhancer();// 用于生成代理对象 enhancer.setSuperclass(this.targetObj.getClass());// 设置代理对象的父类 enhancer.setCallback(this);// 设置代理对象的回调函数就是本生 return enhancer.create();// 生成代理对象 } /* * 当代理对象的方法被调运时,就会执行改代理对象的回调函数,也就是intercept方法 这个回调函数接收代理对象传递来的参数 */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { Object result = null; System.out.print("我是#"); result = proxy.invokeSuper(obj, args); System.out.print("#人"); return result; } }
注意:目标对象不须实现接口。因为生成的代理对象时目标对象的子类。
3.测试上面的代理
public class Main { public static void main(String[] args) { Person zhangsan = new PersonImpl();// 被代理的对象 zhangsan.say();// 如果让代理目标直接执行目标方法,就不能在目标方法前后操作 System.out.println(); PersonProxy proxy = new PersonProxy(zhangsan);// 将被代理的对象传递一个代理类 proxy.say();// 让代理类去执行目标方法,这个时候代理类就在目标方法执行前后乱搞了 PersonProxyJdk proxyJdk = new PersonProxyJdk();// 创建一个代理对象 Person zhangsanJdk = (Person) proxyJdk.createProxyInstance(zhangsan);// 将被代理对象传递给代理对象,并且返回被代理接口 zhangsanJdk.say();// 调运被代理对象的接口,就能动态的去执行代理对象想要执行的操作 PersonProxyCglib proxyCglib = new PersonProxyCglib();// 创建Cglib代理对象 Person zhansanCglib = (Person) proxyCglib.createProxyInstance(zhangsan);// 将被代理对象传递给代理对象,并且返回被代理接口 zhansanCglib.say();// 调运被代理对象的接口,就能动态的去执行代理对象想要执行的操作 // 使用Cglib的时候,目标对象可以不实现任何接口,但是使用JDK代理的时候就不可以 PersonNoImpl lisi = new PersonNoImpl(); PersonNoImpl lisiCglib = (PersonNoImpl) proxyCglib.createProxyInstance(lisi); lisiCglib.say(); } } 输出: 中国 我是-中国-人 我是*中国*人 我是#中国#人 我是#中华人民共和国#人
相关推荐
在Java编程中,有时我们需要模拟用户的网络环境,例如设置IE(Internet Explorer)浏览器的代理以进行自动化测试或者数据抓取。这个"java操作IE代理"的主题涉及到如何在Java程序中控制IE的网络代理设置,这通常需要...
在Java编程中,代理模式是一种常用的面向对象设计模式,它允许我们为一个对象提供一个代理以控制对该对象的访问。代理模式通常用于增加额外的功能,如日志、权限检查等,或者为了创建虚拟代理以提高性能。以下是Java...
在Java编程环境中,当需要通过局域网(LAN)进行网络通信时,有时会遇到需要使用代理服务器的情况。代理服务器可以提供多种功能,包括提高访问速度、缓存、过滤网络内容以及匿名上网等。本文将深入探讨如何在Java中...
### Java代理模式与Java动态代理详解 #### 一、代理模式概述 代理模式是一种软件设计模式,它在客户端和目标对象之间提供了一种间接层。这种模式的主要目的是控制客户端对目标对象的访问,并且可以在不修改原有...
本文将详细介绍如何在Java中使用IE Proxy代理来实现这一功能。 首先,我们需要理解Java中的网络访问机制。Java使用`java.net`包中的`Socket`和`HttpURLConnection`等类来处理网络通信。当程序运行时,它会使用系统...
Java 实现免费代理IP的获取方式 并动态实时校验是否有效,java文件项目内含有Jsoup的Jar包(Jsoup是加工过的,含请求),有2个主入口程序: 其一:用于请求代理IP,并立即校验是否是一个有效的代理IP,如果有效,...
在Java动态代理中,我们首先需要定义一个或多个接口。这些接口定义了原始对象(也称为目标对象)所实现的方法。代理对象将实现这些接口,并在调用这些方法时执行额外的操作。 3. **InvocationHandler接口** `...
在Java编程语言中,代理模式是一种设计模式,它允许我们为一个对象提供一个代理以控制对这个对象的访问。代理模式通常用于增加额外的功能或在访问原对象时进行额外的操作,比如日志记录、安全控制、性能度量等。Java...
3. **拦截器模式**:在Java动态代理中,我们可以使用`InvocationHandler`来实现拦截器。拦截器是一种设计模式,它允许我们在方法调用前后插入自定义的代码,比如事务管理、权限检查等。通过动态代理,我们可以轻松地...
3: 动态代理使用到基础理论:ClassLoader 加载.class字节码文件得到 , Class对象, Class对象通过 newProxyInstance 得到代理对象 4: 动态代理使用到基础理论:Class.forName("xxxx") 得到Class类 。
Java动态代理是Java编程中一个重要的特性,它允许在运行时创建代理对象,这些代理对象可以代表并增强原对象的功能。动态代理主要应用于面向切面编程(AOP)和事件监听等场景,使得代码更加模块化,易于维护。以下是...
在Java中,事务管理可以通过多种方式实现,其中一种高效且灵活的方法是利用动态代理。动态代理可以帮助我们实现事务的透明化管理,使代码更加简洁、清爽。 动态代理是Java提供的一种机制,它允许我们在运行时创建一...
在本文中,我们将探讨如何使用Java的动态代理来实现数据库连接池,从而解决传统连接池设计中的耦合度问题和资源管理问题。 首先,数据库连接池是应用程序管理数据库连接的一种高效方式。它通过复用已建立的数据库...
使用Java编写的反向代理程序(源代码),通过简单的参数配置即可实现某些特定站点的反向代理,并在此过程中改变一些站点的特定行为。例如:允许特点站点跨域访问被代理的站点,或者屏蔽被代理站点识别请求访问客户端...
在动态代理中,我们创建了一个 `DynamicProxy` 类实现 `InvocationHandler` 接口,然后使用 `Proxy.newProxyInstance()` 方法创建代理对象。`invoke()` 方法会拦截所有对代理对象的方法调用,从而可以在调用前后添加...
在Java中,有两种方式实现动态代理:一种是通过Java的标准库`java.lang.reflect.Proxy`,另一种是使用Java的接口`java.lang.reflect.InvocationHandler`。我们先来看Proxy类,它是Java动态代理的核心,它提供了一种...
本主题将深入探讨如何使用Java语言来编写这样的代理服务器。以下是对这个主题的详细解析: 首先,理解HTTP代理服务器的基本原理是必要的。HTTP代理服务器作为客户端与目标服务器之间的中介,它接收客户端的HTTP请求...
在Java中,静态代理是通过在代理类中显式实现目标接口来实现的。下面将详细介绍静态代理模式的概念、作用、实现方式以及其优缺点。 ### 1. 静态代理概念 静态代理模式是一种结构型设计模式,其核心思想是通过创建一...
在Java编程领域,动态代理和Cglib代理是两种常用的技术,用于在运行时创建对象的代理,以实现额外的功能,如AOP(面向切面编程)中的日志、事务管理等。本篇文章将深入探讨这两种代理机制,尤其是Cglib代理。 首先...
在Java中,动态代理主要通过两个类来实现:`java.lang.reflect.Proxy` 和 `java.lang.reflect.InvocationHandler`。 1. **Proxy类**: `Proxy` 类是Java提供的一个内部类,它主要用于创建一个实现了指定一组接口的...