1. 程式人生 > >java實現動態代理的三種方法

java實現動態代理的三種方法

緒論:以下三種java實現動態代理的的方式,分別為基於jdk的,基於cglib的和基於javassist的,其中需要注意的兩點

一:基於jdk實現的動態代理需要實現父類,而其他兩種不需要

二:其中基於cglib的需要額外的jar包依賴,pom的依賴如下

<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>2.2</version>
</dependency>

為了方便,測試類寫在了一起,程式碼如下:

package info.lumanman.mybatis.entry.proxy;

public class People implements PeopleInterface{

	public String getInfo(int age){
		System.out.println("執行中--張三的年齡:"+age);
		return "張三的年齡:"+age;
	}
}
package info.lumanman.mybatis.entry.proxy;

public interface PeopleInterface {

	public String getInfo(int age);
}
package info.lumanman.mybatis.entry.proxy;

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

import org.junit.Test;

import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyFactory;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class ProxyTest {

	@Test
	public void testJdkProxy() {
		 final People people=new People();
		PeopleInterface proxy=(PeopleInterface) Proxy.newProxyInstance(ProxyTest.class.getClassLoader(), 
				People.class.getInterfaces(), new InvocationHandler() {
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				System.out.println("代理前");
				Object result=method.invoke(people, args);
				System.out.println("代理後");
				return result;
			}
		});
		
		String result=proxy.getInfo(18);
		System.out.println("執行結果:"+result);
	}
	
	@Test
	public void testCglibProxy() {
		People people=new People();
		
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(people.getClass());
		enhancer.setCallback(new MethodInterceptor() {
			public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
				System.out.println("前置處理");
				Object result=proxy.invokeSuper(obj, args);
				System.out.println("後置處理");
				return result;
			}
		});
		People proxy=(People)enhancer.create();
		
		String result= proxy.getInfo(19);
		System.out.println("執行結果:"+result);
	}
	
	@Test
	public void testJavassistProxy() throws Exception {
		ProxyFactory factory=new ProxyFactory();
		factory.setSuperclass(People.class);
		factory.setFilter(new MethodFilter() {//過濾器可以對方法進行過濾,不加也行
			
			public boolean isHandled(Method m) {
				//if(m.getName().equals("execute")){
					return true;
				//}
				//return false;
			}
		});
		
		factory.setHandler(new MethodHandler() {
			
			public Object invoke(Object self, Method thisMethod, Method proceed, Object[] args) throws Throwable {
				System.out.println("前置處理");
				Object result=proceed.invoke(self, args);
				System.out.println("後置處理");
				return result;
			}
		});
		
		Class<?> c=factory.createClass();
		People proxy=(People) c.newInstance();
		String result= proxy.getInfo(19);
		System.out.println("執行結果:"+result);
	}

}

參考:《mybatis技術內幕》