Java动态代理讲解和示例

开发 前端
Java 动态代理底层原理是基于反射机制实现的,其中最重要的是 InvocationHandler 接口,它定义了一个 invoke() 方法,用于实现对代理类中各个方法的调用,在 invoke() 方法中,可以实现对真实角色的调用,并进行扩展,实现动态代理的效果。

Java动态代理是一种在运行时创建代理类的机制,动态代理可以在不修改源代码的情况下,在运行时为某个接口动态生成实现类,并且可以拦截接口中的方法调用,从而实现一些特殊的功能。

Java 动态代理底层原理是基于反射机制实现的,其中最重要的是 InvocationHandler 接口,它定义了一个 invoke() 方法,用于实现对代理类中各个方法的调用,在 invoke() 方法中,可以实现对真实角色的调用,并进行扩展,实现动态代理的效果。

动态代理的实现步骤:

1. 创建一个实现 InvocationHandler 接口的类,它必须实现 invoke() 方法;

2. 创建被代理的真实对象;

3. 通过 Proxy 类的 newProxyInstance() 方法创建代理对象,它需要参数:

(1)ClassLoader:类加载器,它是用于加载代理对象字节码的,和被代理对象使用相同的类加载器;

(2)Class[]:字节码数组,它是用于让代理对象和被代理对象有相同方法;

(3)InvocationHandler:它是调用处理器,执行代理对象的方法时,会触发该对象的 invoke() 方法;

4. 通过代理对象调用目标方法,实际上会转到 invoke() 方法中,在 invoke() 方法中,可以进行预处理、调用后处理等工作。

反射上一篇文章讲过了,这里就是反射的一个应用,这个最常见的场景就是给代码加日志,例如在执行某个函数前将请求体加入到日志中,执行后将结果加入到日志中。这样可以在不改变原来代码的基础上来实现。接下来就使用上一篇反射的例子继续扩展。

先写一个Person的接口:

package ReflectTest;

public interface PersonInterface {
void printName();
void printAge();
}

写他的实现:

package ReflectTest;

public class Person implements PersonInterface{
private String name = "xiaoming";
private String age = "12";

@Override
public void printName()
{
System.out.println(name);
}
@Override
public void printAge()
{
System.out.println(age);
}
}

然后写动态代理类:

package ReflectTest;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyHandler implements InvocationHandler {
private Object target;
public ProxyHandler(Object target) {
this.target = target;
}

public Object bind() {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行函数前加入日志");
Object result = method.invoke(target, args);
System.out.println("执行函数后加入日志");
return result;
}
}

最后测试一下:

package ReflectTest;

public class main {

public static void main(String[] args) {
ProxyHandler proxyHandler = new ProxyHandler(new Person());
PersonInterface person = (PersonInterface)proxyHandler.bind();
person.printName();
}

}

我们看看结果在执行函数前后执行了其他操作:

SpringAOP其实原理就类似这种。

责任编辑:姜华 来源: 今日头条
相关推荐

2011-11-17 14:32:45

Java静态代理动态代理

2023-12-06 08:23:44

代理模式设计模式

2021-07-06 06:39:22

Java静态代理动态代理

2011-04-06 11:41:25

Java动态代理

2012-08-28 10:59:26

JavaJava动态代理Proxy

2022-06-27 10:26:37

枚举Java

2023-11-26 00:13:16

开源数据Logstash

2017-10-12 14:56:11

2011-03-23 10:40:51

java代理模式

2015-09-22 11:09:47

Java 8动态代理

2015-09-28 15:59:00

Java动态代理机制

2017-05-11 21:30:01

Android动态代理ServiceHook

2009-12-28 15:45:22

动态网络接入控制

2015-09-24 08:54:36

java动态代理

2015-09-24 08:55:14

Java动态代理扩展

2010-01-28 16:01:18

Android Jni

2012-02-08 10:12:19

Java反射

2010-04-21 09:26:54

Java动态代理

2020-04-27 07:28:00

Java反射动态代理

2018-04-16 10:12:46

Linux命令gunzip
点赞
收藏

51CTO技术栈公众号