JDK动态代理和Cglib的动态代理

匆匆过客 提交于 2020-03-24 13:37:14

3 月,跳不动了?>>>

最简单的是静态代理方法,即代理模式,这里就不多啰嗦了。。

重点说一下JDK的动态代理和Cglib的动态代理吧

先说JDK的,需要被代理的类需要有接口,否则无法实现

package proxy.dynamic;

public interface IBook {
	void add();
}

实现接口的类如下

package proxy.dynamic;

public class Book implements IBook {

	@Override
	public void add() {
		System.out.println("Add Method!");
	}

	

}

创建一个代理类,需要实现一个接口InvocationHandler接口,里面有一个invoke方法需要实现

同时创建一个生成实例的方法

package proxy.dynamic;

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

public class BookProxy implements InvocationHandler{
	private Object target;
	
	public Object bind(Object target) {
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);//这里需要接口
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result=null;
		System.out.println("Before");
		result=method.invoke(target, args);//执行方法
		System.out.println("After");
		return result;
	}
	

	

}

接下来创建测试类

package proxy.dynamic;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		BookProxy bp = new BookProxy();
		IBook book = (IBook) bp.bind(new Book());
		book.add();

	}

}

可以看到依次输出了Before,方法,After


下面说一下Cglib的代理,Cglib代理不需要原类实现接口,依赖Cglib和asm两个Jar包

需要代理的类如下

package cglib.proxy;

public class Book {

	public void add() {
		System.out.println("Add Method!");
	}
}

创建一个代理类,实现MethodInterceptor接口,同时写一个生成实例的getInstance方法

package cglib.proxy;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{
	private Object target;
	public Object getInstance(Object target){
		this.target=target;
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(this.target.getClass());
		enhancer.setCallback(this);
		return enhancer.create();
	}
	@Override
	public Object intercept(Object obj, Method method, Object[] args,
			MethodProxy proxy) throws Throwable {
		
		System.out.println("Before");
		proxy.invokeSuper(obj, args);
		System.out.println("After");
		return null;
	}

	

}

接下来就是简单测试一下

package cglib.proxy;

public class Test {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CglibProxy proxy = new CglibProxy();
		Book book=(Book) proxy.getInstance(new Book());
		book.add();

	}

}

运行效果一样的

简单总结一下,JDK动态代理,需要实现一个接口InvocationHandler,要求被代理的对象必须有一个接口

Cglib代理需要实现MethodInterceptor接口,不需要被代理的类必须有接口

性能方法,参考其他文章,说JDK代理适合多例模式,而单例模式Cglib更好一些,因为Cglib是用底层的字节码技术生成实例,耗费时间较长,性能不如JDK动态代理。(有待验证。。)


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!