JDK動態代理和Cglib的動態代理

最簡單的是靜態代理方法,即代理模式,這裏就很少囉嗦了。。java

重點說一下JDK的動態代理和Cglib的動態代理吧ide

先說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方法須要實現this

同時建立一個生成實例的方法spa

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,方法,Aftercode


下面說一下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動態代理。(有待驗證。。)

相關文章
相關標籤/搜索