动态代理的原理
Posted 杨斌并
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态代理的原理相关的知识,希望对你有一定的参考价值。
Proxy.newProxyInstance 代理需要代理一个接口或者接口的实现类,但是必须有接口
代理一个接口
interface IPerson
fun eat(eat: String);
fun read(content: String): String;
val p = Proxy.newProxyInstance(
classLoader,
arrayOf(IPerson::class.java),
InvocationHandler proxy, method, args ->
if ("eat" == method.name)
println("调用了eat $args[0]")
else if ("read" == method.name)
println("调用了read $args[0]")
return@InvocationHandler "红楼梦"
null
) as IPerson
p.eat("茶")
val read = p.read("西游记")
println(read)
代理一个实现了一个接口的实体类
public interface Person
String read();
void eat();
public class Teacher implements Person
@Override
public String read()
System.out.println("我读书了");
return "小学课本";
@Override
public void eat()
System.out.println("eat 学校套餐");
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class PersonHandler<T> implements InvocationHandler
private T t;
PersonHandler(T t)
this.t = t;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
System.out.println(method.getName());
if ("eat".equals(method.getName()))
System.out.println("调用了eat前");
Object invoke = method.invoke(t, args);
System.out.println("调用了eat后");
return invoke;
else if ("read".equals(method.getName()))
System.out.println("调用了read前");
Object invoke = method.invoke(t, args);
System.out.println("调用了read后");
return invoke;
return method.invoke(t, args);
public void invoke()
val teacher = Teacher()
val p = Proxy.newProxyInstance(
Teacher::class.java.classLoader,
arrayOf(Person::class.java),
PersonHandler(teacher)
) as Person
p.eat()
p.read()
CGLIB代理 可以代理一个实体类不需要接口
public class UserService
public void getName()
System.out.println("张三!");
public class ProxyFactory<T> implements MethodInterceptor
private T target;
public ProxyFactory(T target)
this.target = target;
// 创建代理对象
public Object getProxyInstance()
// 1.cglib工具类
Enhancer en = new Enhancer();
// 2.设置父类
en.setSuperclass(this.target.getClass());
// 3.设置回调函数
en.setCallback(this);
return en.create();
//拦截方法
@Override
public Object intercept(Object obj, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable
System.out.println("开始事务...");
// 执行目标对象的方法
Object result = method.invoke(target, args);
System.out.println("提交事务...");
return result;
以上是关于动态代理的原理的主要内容,如果未能解决你的问题,请参考以下文章
DouPHP去除Powered by DouPHP版权的方法