JDK动态代理
- 只能代理接口
- 思路是新建一个接口的实现类,并持有需要被代理的实现类。将被代理的对象方法进行增强。
- 定义一个接口
public interface Animal {
String run();
String jump();
}
- 需要代理的类
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";
}
}
- 代理类,需要以
Proxy
结尾
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
- 可以代理普通类
- 思路是新建一个子类继承需要被代理的目标类,通过继承的方式持有原来的方法
- 通过字节码操作形成新的类,会占用方法区(元空间)的空间,过于频繁的操作肯能会导致内存溢出
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);
}
}
网友评论