7-設計模式-代理模式

代理模式

什麼是代理?

經過代理控制對象的訪問,能夠詳細訪問某個對象的方法,在這個方法調用處理,或調用後處理。既(AOP微實現)  ,AOP核心技術面向切面編程。java

代理應用場景

安全代理 能夠屏蔽真實角色spring

遠程代理 遠程調用代理類RMI編程

延遲加載 先加載輕量級代理類,真正須要在加載真實安全

代理的分類

靜態代理(靜態定義代理類)ide

動態代理(動態生成代理類)this

Jdk自帶動態代理spa

Cglib 、javaassist(字節碼操做庫)代理

靜態代理

靜態代理須要本身生成代理類code

public interface Hose {

	/**
	 * 
	 * @methodDesc: 功能描述:(買房代理)
	 * @author: 餘勝軍
	 * @param:
	 * @createTime:2017年8月27日 上午2:54:34
	 * @returnType: void
	 * @copyright:上海每特教育科技有限公司
	 */
	public void mai();

}

public class XiaoMing implements Hose {
	@Override
	public void mai() {
		System.out.println("我是小明,我要買房啦!!!!haha ");
	}
}
class Proxy  implements Hose {
	private XiaoMing xiaoMing;
	public Proxy(XiaoMing xiaoMing) {
		this.xiaoMing = xiaoMing;
	}
	public void mai() {
		System.out.println("我是中介 看你買房開始啦!");
		xiaoMing.mai();
		System.out.println("我是中介 看你買房結束啦!");
	}
	public static void main(String[] args) {
		Hose proxy = new Proxy(new XiaoMing());
		proxy.mai();
	}
}

JDK動態代理(不須要生成代理類)

實現InvocationHandler 就能夠了。對象

public interface Hose {

	/**
	 * 
	 * @methodDesc: 功能描述:(買房代理)
	 * @author: 餘勝軍
	 * @param:
	 * @createTime:2017年8月27日 上午2:54:34
	 * @returnType: void
	 * @copyright:上海每特教育科技有限公司
	 */
	public void mai();

}


public class XiaoMing implements Hose {

	@Override
	public void mai() {
		System.out.println("我是小明,我要買房啦!!!!haha ");
	}

}
public class JDKProxy implements InvocationHandler {
	private Object tarjet;

	public JDKProxy(Object tarjet) {
		this.tarjet = tarjet;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("我是房產中介.....開始監聽你買房啦!");
		Object oj = method.invoke(tarjet, args);
		System.out.println("我是房產中介.....結束監聽你買房啦!");
		return oj;

	}

}

class Test222 {
	public static void main(String[] args) {
		XiaoMing xiaoMing = new XiaoMing();
		JDKProxy jdkProxy = new JDKProxy(xiaoMing);
		Hose hose=(Hose) Proxy.newProxyInstance(xiaoMing.getClass().getClassLoader(), xiaoMing.getClass().getInterfaces(), jdkProxy);
		hose.mai();
	}

}

CGLIB動態代理

import java.lang.reflect.Method;

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

public interface Hose {

	/**
	 * 
	 * @methodDesc: 功能描述:(買房代理)
	 * @author: 餘勝軍
	 * @param:
	 * @createTime:2017年8月27日 上午2:54:34
	 * @returnType: void
	 * @copyright:上海每特教育科技有限公司
	 */
	public void mai();

}


public class XiaoMing implements Hose {

	@Override
	public void mai() {
		System.out.println("我是小明,我要買房啦!!!!haha ");
	}

}

public class Cglib implements MethodInterceptor {

	@Override
	public Object intercept(Object o, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		System.out.println("我是買房中介 , 開始監聽你買房了....");
		Object invokeSuper = methodProxy.invokeSuper(o, args);
		System.out.println("我是買房中介 , 開結束你買房了....");
		return invokeSuper;

	}

}

class Test22222 {
	public static void main(String[] args) {
		Cglib cglib = new Cglib();
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(XiaoMing.class);
		enhancer.setCallback(cglib);
		Hose hose = (Hose) enhancer.create();
		hose.mai();
	}
}

CGLIB與JDK動態代理區別

區別:

java動態代理是利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。而cglib動態代理是利用asm開源包,對代理對象類的class文件加載進來,經過修改其字節碼生成子類來處理。

一、若是目標對象實現了接口,默認狀況下會採用JDK的動態代理實現AOP 

二、若是目標對象實現了接口,能夠強制使用CGLIB實現AOP 

三、若是目標對象沒有實現了接口,必須採用CGLIB庫,spring會自動在JDK動態代理和CGLIB之間轉換
相關文章
相關標籤/搜索