aop底層JDK動態代理與cglib代理模式簡單實現

一、JDK代理示例java

JDK動態代理只能對實現了接口的類生成代理,不能針對類代理,JDK動態代理須要以下類:接口、實現類、實現InvocationHandler接口的代理類(這個類中包括如下方法:能夠傳入目標對象的構造函數,InvocationHandler接口方法的實現能夠執行目標方法,獲得目標對象的代理對象)spring

代碼示例以下:接口框架

package jicu.proxy.jdk;

public interface Print {
	
	void printWords();
	
	void printNumbers();

}

實現類:ide

package jicu.proxy.jdk;

public class PrintImpl implements Print {

	public PrintImpl() {
		// TODO Auto-generated constructor stub
	}

	@Override
	public void printWords() {
		// TODO Auto-generated method stub
		System.out.println("this is PrintImpl printWords()");
		
	}

	@Override
	public void printNumbers() {
		// TODO Auto-generated method stub
		System.out.println("this is PrintImpl printNumbers()");
		
	}

}

代理類:函數

package jicu.proxy.jdk;

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

public class JdkProxy implements InvocationHandler {

	private Object object;

	/**
	 * 構造方法傳入目標對象
	 * 
	 * @param object
	 */
	public JdkProxy(Object object) {
		// TODO Auto-generated constructor stub
		this.object = object;
	}

	/**
	 * 執行目標對象的方法
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("before method invoke");
		// 執行目標對象的方法
		Object o = method.invoke(object, args);
		System.out.println("after method invoke");
		return o;
	}

	/**
	 * 獲取目標對象的代理對象
	 * 
	 * @return
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), object.getClass().getInterfaces(),
				this);
	}

}

測試方法:測試

package jicu.proxy.jdk;

public class TestMain {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		// 目標對象
		Print print = new PrintImpl();
		// 代理類
		JdkProxy jdkProxy = new JdkProxy(print);
		// 代理對象
		Print printProxy = (Print) jdkProxy.getProxy();
		printProxy.printWords();
		printProxy.printNumbers();

	}

}

二、cglib是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法,其底層是經過使用一個小而塊的字節碼處理框架ASM,來轉換字節碼並生成新的類this

cglib代理示例代理

package soundsystem;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxy {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(CglibProxy.class);
		enhancer.setCallback(new MethodInterceptorImpl());
		// 生成代理對象
		CglibProxy cgPxocy = (CglibProxy) enhancer.create();
		cgPxocy.test();

	}

	public void test() {
		// TODO Auto-generated method stub
		System.out.println("this is CglibProxy test()");
	}

	/**
	 * 經過代理對象調用目標方法
	 * 
	 * @author timi
	 *
	 */
	private static class MethodInterceptorImpl implements MethodInterceptor {

		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			// TODO Auto-generated method stub
			System.out.println("before invoke");
			Object o = proxy.invokeSuper(obj, args);
			System.out.println("after invoke");
			return o;
		}

	}

}
相關文章
相關標籤/搜索