Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类。
代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过程中,开发人员还可以按需调整委托类对象及其功能
代理是一种常用的设计模式,其目的就是为其他对象提供一个代理以控制对某个对象的访问。代理类负责为委托类预处理消息,过滤消息并转发消息,以及进行消息被委托类执行后的后续处理。
要了解 Java 动态代理的机制,首先需要了解以下相关的类或接口:
java.lang.reflect.Proxy:这是 Java 动态代理机制的主类,它提供了一组静态方法来为一组接口动态地生成代理类及其对象
// 方法 1: 该方法用于获取指定代理对象所关联的调用处理器
static InvocationHandler getInvocationHandler(Object proxy)
// 方法 2:该方法用于获取关联于指定类装载器和一组接口的动态代理类的类对象
static Class getProxyClass(ClassLoader loader, Class[] interfaces)
// 方法 3:该方法用于判断指定类对象是否是一个动态代理类
static boolean isProxyClass(Class cl)
// 方法 4:该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)
java.lang.reflect.InvocationHandler:这是调用处理器接口,它自定义了一个 invoke 方法,用于集中处理在动态代理类对象上的方法调用,通常在该方法中实现对委托类的代理访问。
// 该方法负责集中处理动态代理类上的所有方法调用。
// 第一个参数既是代理类实例,
// 第二个参数是被调用的方法对象
// 第三个方法是调用参数。
// 调用处理器根据这三个参数进行预处理或分派到委托类实例上发射执行
Object invoke(Object proxy, Method method, Object[] args)
每次生成动态代理类对象时都需要指定一个实现了该接口的调用处理器对象
java.lang.ClassLoader:这是类装载器类,负责将类的字节码装载到 Java 虚拟机(JVM)中并为其定义类对象,然后该类才能被使用。Proxy 静态方法生成动态代理类同样需要通过类装载器来进行装载才能使用,它与普通类的唯一区别就是其字节码是由 JVM 在运行时动态生成的而非预存在于任何一个 .class 文件中
每次生成动态代理类对象时都需要指定一个类装载器对象
首先让我们来了解一下如何使用 Java 动态代理。具体有如下四步骤:
1通过实现 InvocationHandler 接口创建自己的调用处理器;
2通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
3通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
4通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入
动态代理对象创建过程
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
// 其内部通常包含指向委托类实例的引用,用于真正执行分派转发过来的方法调用
InvocationHandler handler = new InvocationHandlerImpl(..);
// 通过 Proxy 为包括 Interface 接口在内的一组接口动态创建代理类的类对象
Class clazz = Proxy.getProxyClass(classLoader, new Class[] { Interface.class, ... });
// 通过反射从生成的类对象获得构造函数对象
Constructor constructor = clazz.getConstructor(new Class[] { InvocationHandler.class });
// 通过构造函数对象创建动态代理类实例
Interface Proxy = (Interface)constructor.newInstance(new Object[] { handler });
简化的动态代理对象创建过程
// InvocationHandlerImpl 实现了 InvocationHandler 接口,并能实现方法调用从代理类到委托类的分派转发
InvocationHandler handler = new InvocationHandlerImpl(..);
// 通过 Proxy 直接创建动态代理类实例
Interface proxy = (Interface)Proxy.newProxyInstance( classLoader,
new Class[] { Interface.class }, handler );
package com.ljh.proxy;
public interface Sell {
public void sell();
public void modiy(float price);
}
package com.ljh.test;
import com.ljh.proxy.Sell;
/**
* 真实角色 Dell
* @author Administrator
*
*/
public class Dell implements Sell {
@Override
public void sell() {
System.out.println("Dell sell computer");
}
@Override
public void modiy(float price) {
System.out.println("Dell modify computer neet "+ price);
}
}
package com.ljh.test;
import com.ljh.proxy.Sell;
/**
* 真实角色 Lenover
* @author Administrator
*
*/
public class Lenover implements Sell{
@Override
public void sell(){
System.out.println("Lenover sell computer");
}
@Override
public void modiy(float price) {
System.out.println("Lenover modify computer neet "+price);
}
}
package com.ljh.proxy.impl;
import java.io.Serializable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 调用处理器
* @author Administrator
*
*/
public class SellProxy implements InvocationHandler,Serializable{
private static final long serialVersionUID = 1467717578378167352L;
private Object proxy;//为谁生成代理类
public SellProxy(Object obj){
this.proxy = obj;
}
@Override
public Object invoke(Object proxy, //代理类实例
Method method,//被调用的方法对象
Object[] args //方法是调用参数
) throws Throwable {
Object object ;
before();
object = method.invoke(this.proxy, args);
after();
return object;
}
private void after() {
System.out.println("after");
}
private void before() {
System.out.println("before");
}
}
package com.ljh.test;
import java.lang.reflect.Proxy;
import com.ljh.proxy.Sell;
import com.ljh.proxy.impl.SellProxy;
public class ProxyTest {
public static void main(String[] args) {
//创建真实角色类
Sell sell = new Lenover();
//创建调用管理器类
SellProxy handler = new SellProxy(sell);//传入需要需要代理的真实角色
Sell proxy = (Sell) Proxy.newProxyInstance(
sell.getClass().getClassLoader(), //指定加载器来加载动态生成的代理类字节码
new Class[]{Sell.class},// 根据指定一组接口来生成代理类的实例
handler);// 调用处理器类
proxy.sell();
}
}
分享到:
相关推荐
### Java 动态代理Proxy应用和底层源码分析 #### 一、Java动态代理简介 Java动态代理是一种在运行时动态生成代理类的技术,通过该技术可以为一个或多个接口生成一个实现类,该实现类可以拦截接口方法的调用,并...
JDK动态代理,全称为Java Dynamic Proxy,是Java标准库提供的一种强大且灵活的机制,允许我们在运行时创建代理类来实现指定的接口。这种机制主要用于实现AOP(面向切面编程)或为已有接口提供额外的功能,如日志、...
Java中的动态代理是实现AOP的一种方式,特别是对于接口的代理。下面我们将详细探讨如何在Java中实现基于接口的动态代理,以及其背后的原理。 首先,我们需要定义一个接口,这个接口包含了我们真正想实现的业务逻辑...
在Java编程中,动态代理(Dynamic Proxy)是一种强大的设计模式,它允许我们在运行时创建具有特定接口的新对象。Java的动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口...
动态代理类例子proxy动态代理类例子proxy动态代理类例子proxy
在Java中,动态代理主要通过`java.lang.reflect.Proxy`类和`java.lang.reflect.InvocationHandler`接口来实现。Proxy类是用于创建一个代理对象,而InvocationHandler接口则定义了代理对象调用方法时的行为。 1. **...
总结来说,Java动态代理通过`Proxy`和`InvocationHandler`提供了灵活的代码扩展机制,可以在运行时为对象创建代理,实现在不修改原有代码的基础上添加额外功能。这在处理需要拦截和增强的对象时非常有用,例如日志...
本文将深入探讨Java中的动态代理,特别是基于`java.lang.reflect.Proxy`类的使用。 首先,`java.lang.reflect.Proxy`是Java标准库中用于生成动态代理类的关键类。它允许我们创建一个新的接口实现类,而无需手动编写...
AOP 动态代理(Proxy invocationHandler),Spring的动态代理的介绍
此文比较详细讲述了Nginx与proxy共同搭建反向代理服务的配置方法
"ArcGIS JS API跨域配置 Proxy 代理" ArcGIS JS API 跨域配置是指在 JS 开发中遇到的访问本地服务和外网服务的问题,需要使用 Proxy 代理来解决跨域访问文件的问题。ArcGIS 的帮助中已经有了相关的介绍和使用配置。...
Nginx在vhost里的配置站点,通过proxy转发到动态域名的具体配置。 反向代理,动态域名 ,Proxy
《GoProxy-Android:全能代理服务器在安卓平台的应用与实现》 GoProxy-Android是由snail007/goproxy团队开发的一款适用于安卓系统的全能代理服务器应用。此项目旨在为移动设备提供强大的网络代理功能,使得用户能够...
【标题】:“JDBC Proxy 代理类” 在Java开发中,JDBC(Java Database Connectivity)是连接数据库的主要方式。然而,直接使用JDBC代码往往繁琐且易出错,因此引入了代理类(Proxy Class)的概念,它能为JDBC提供更...
简易高效的代理池,提供如下功能: 1. 定时抓取免费代理网站,简易可扩展 2. 使用 Redis 对代理进行存储...Github 链接:https://github.com/Python3WebSpider/ProxyPool 详情阅读:README.md,使用方法及相关信息讲解
在这个“java proxy demo”中,我们将深入探讨如何利用Sun JDK API来创建和使用Java动态代理。 首先,我们要了解Java代理的基本概念。Java代理分为静态代理和动态代理两种。静态代理是在编译时就已经确定代理类的...
这里我们探讨的“spring proxy代理模仿”主要指的是Spring AOP(面向切面编程)中的动态代理实现。Spring AOP通过代理模式为我们提供了在运行时向目标对象添加拦截器或切面的能力,这在进行日志记录、性能监控、事务...
在Java编程语言中,反射(Reflection)和动态代理(Dynamic Proxy)是两个强大的特性,它们为程序员提供了在运行时检查和操作类、接口、对象的能力。这篇内容将深入讲解这两个概念,帮助初学者理解并掌握它们的应用...