java jdk與cglib動態代理模式的認識和實現

1.使用java jdk Proxy實現動態代理,該原理是反射機制。

創建一個普通的接口java

package com.tester.cls.design.mode;

public interface IUser {

	public String getName();

	public void setName(String name);
	
	public void setUser(int id,String name);
	
	public int getId();

	public void setId(int id);
}

構建一個實現類(簡單的javaBean)ide

package com.tester.cls.design.mode;


public class User  implements IUser{

	private int id;
	
	private String name;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void setUser(int id,String name) 
	{
		setId(id);
		setName(name);
	}
	
	@Override
	public String toString() {
		return super.toString();
	}
	
}

實現代理測試

InvocationHandler實質是攔截器,用來攔截動態代理的方法調用。this

Proxy纔是動態代理,攔截器攔截Proxy生成的代理對象的方法spa

package com.tester.cls.design.mode;

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

public  class ObjectProxy implements InvocationHandler{

	IUser delegateTarget = null;

		public  IUser delegate(IUser delegateTarget)
	{
		this.delegateTarget =  delegateTarget;
		return  (IUser) Proxy.newProxyInstance(ObjectProxy.class.getClassLoader(), delegateTarget.getClass().getInterfaces(),this);
	}
	
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		System.out.println(method.getName()+"-"+method.getReturnType());
		return method.invoke(delegateTarget, args);
	}
	

}

測試,測試一下代理

public static void main(String[] args) {
		
		User u = new User();
		
		ObjectProxy objHandler = new ObjectProxy();
		IUser delegate = objHandler.delegate(u); //注意,返回值的類型是註解類型
		
		delegate.setUser(2014, "zhangsan");
		
		System.out.println(delegate.getId()+"-"+delegate.getName());
		System.out.println(u.getId()+"-"+u.getName());
		
		u.setUser(2048, "張三");
		
		System.out.println(delegate.getId()+"-"+delegate.getName());
		System.out.println(u.getId()+"-"+u.getName());
	
	}

輸出結果code

2014-zhangsan
2014-zhangsan
2048-張三
2048-張三


2.使用cglib.jar實現動態代理,原理是操做底層字節碼

Cglib實現動態代理,Cglib的效率高於JDK動態代理,由於Cglib是有底層字節碼方式生產一個代理類的(此觀點來自於互聯網,本人水平有限,目前只將概念)。對象

cglib使用底層ASM實現動態類的繼承(很牛逼吧,咱們平常使用的類是靜態繼承的,這簡直是逆天的趕腳啊~~),能力好的童鞋建議去看源碼。繼承

(注:此處不提供 cglib.jar下載)接口

public class CglibProxy implements MethodInterceptor{
 private Enhancer enhancer = new Enhancer();
 public Object getProxy(Class clazz){
  //設置須要建立子類的類
  enhancer.setSuperclass(clazz); 
  enhancer.setCallback(this);
  //經過字節碼技術動態建立子類實例
  return enhancer.create(); 
 }
 //實現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;
 }
}

測試以下,但不提供結果

public class DoCGLib {
 public static void main(String[] args) {
  CglibProxy proxy = new CglibProxy();
  //經過生成子類的方式建立代理類
  SayHello proxyImp = (SayHello)proxy.getProxy(SayHello.class);
  proxyImp.say();
 }
}


好了,這就是動態代理的基本認識

try doing it;

相關文章
相關標籤/搜索