0%

JDK动态代理和CGLIB

文章字数:340,阅读全文大约需要1分钟

JDK动态代理

  • 只能代理接口
  • 思路是新建一个接口的实现类,并持有需要被代理的实现类。将被代理的对象方法进行增强。
  1. 定义一个接口

    1
    2
    3
    4
    public interface Animal {
    String run();
    String jump();
    }
  2. 需要代理的类

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Dog implements Animal {
@Override
public String run(){
System.out.println("Dog Running...");
return "ok";
}

@Override
public String jump() {
System.out.println("Dog Jumping...");
return "ok";
}
}
  1. 代理类,需要以Proxy结尾
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public class DogProxy implements InvocationHandler {
    // 目标类,也就是被代理对象
    private Object target;

    public void setTarget(Object target)
    {
    this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    System.out.println("前置动作");
    Object result = method.invoke(target, args);
    System.out.println("后置动作");
    }

    // 生成代理类
    public Object CreatProxyedObj()
    {
    return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
    }
    }

CGLIB

  • 可以代理普通类
  • 思路是新建一个子类继承需要被代理的目标类,通过继承的方式持有原来的方法
  • 通过字节码操作形成新的类,会占用方法区(元空间)的空间,过于频繁的操作肯能会导致内存溢出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class CglibProxy implements MethodInterceptor
{
// 根据一个类型产生代理类,可以放在其他地方
public Object CreatProxyedObj(Class<?> clazz)
{
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}

@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable
{
System.out.println("前置操作");
return arg3.invokeSuper(arg0, arg2);
}
}