阿里雲大學JavaWeb開發系列課程:Spring框架入門第十講動態代理

動態代理

1、動態代理和靜態代理的角色是一樣的。

2、動態代理的代理類是動態生成的。

3、分爲兩類,一類基於接口動態代理和基於類的動態代理。

a)基於接口動態代理——jdk動態代理

b)基於類的動態代理——cglib

現在javassist來生成動態代理

4、jdk動態代理——Proxy類和InvocationHander接口

5、InvocationHandler是代理實例的調用處理程序實現的接口。

6、每個代理實例都具有一個關聯的調用處理程序。對代理實例調用方法時,將對方法調用進行編碼並將其指派到它的調用處理程序的invoke方法。

Object invoke(Object proxy,Method method,Object[] args)在代理實例上處理方法調用並返回結果。

在代理實例上處理方法調用並返回結果。在與方法關聯的代理實例上調用方法時,將在調用處理程序上調用此方法。

參數:

proxy——在其上調用方法的代理實例

method——對應於在代理實例上調用的接口方法的Method實例。Method對象的聲明類將是在其中聲明方法的接口,該接口可以是代理類賴以繼承方法的代理接口的超接口。

args——包含傳入代理實例上方法調用的參數值的對象數組,如果接口方法不使用參數,則爲null。基本類型的參數被包裝在適當基本包裝器類(如java.lang.Integer或java.lang.Boolean)的實例中。

返回:

從代理實例的方法調用返回的值。如果接口方法的聲明返回類型是基本類型,則此方法返回的值一定是相應基本包裝對象類的實例;否則,它一定是可分配到聲明返回類型的類型。如果此方法返回的值爲null並且接口方法的返回類型是基本類型,則代理實例上的方法調用將拋出NullPointerException。否則,如果此方法返回的值與上述接口方法的聲明返回類型不兼容,則代理實例上的方法調用將拋出ClassCastException。

Proxy提供用於創建動態代理類和實例的靜態方法,它還是由這些方法創建的所有動態代理類的超類。

Client.java

package cn.sxt.dynamicproxy;


public class Client {
	public static void main(String[] args) {
		Host host=new Host();
		ProxyInovationHandler pih =new ProxyInovationHandler();
		pih.setRent(host);
		Rent proxy =(Rent)pih.getProxy();
		proxy.rent();
	}
}

Host.java

package cn.sxt.dynamicproxy;

public class Host implements Rent {
	public void rent() {
		System.out.println("房屋出租");
	}
}

ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

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

public class ProxyInovationHandler implements InvocationHandler{
	private Rent rent;
	
	
	public void setRent(Rent rent) {
		this.rent = rent;
	}
	/*
	 * 生成代理類
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				rent.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理類
	 * method 代理類的調用處理程序的方法對象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		seeHouse();
		Object result =method.invoke(rent, args);
		fare();
		return result;
	}
	private void seeHouse() {
		System.out.println("帶房客看房");
	}
	//收中介費
	private void fare() {
		System.out.println("收取中介費");
	}

}

Rent.java

package cn.sxt.dynamicproxy;

public interface Rent {
	public void rent() ;
}

ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

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

public class ProxyInovationHandler implements InvocationHandler{
	private Object target;//目標對象——真實對象
	public void setTarget(Object target) {
		this.target = target;
	}
	/*
	 * 生成代理類
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理類
	 * method 代理類的調用處理程序的方法對象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		seeHouse();
		Object result =method.invoke(target, args);
		fare();
		return result;
	}
	//看房
	private void seeHouse() {
		System.out.println("帶房客看房");
	}
	//收中介費
	private void fare() {
		System.out.println("收取中介費");
	}

}

Client.java

package cn.sxt.dynamicproxy;

import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;

public class Client {
	public static void main(String[] args) {
		UserService userService=new UserServiceImpl();
		ProxyInovationHandler pih =new ProxyInovationHandler();
		pih.setTarget(userService);
		UserService proxy =(UserService)pih.getProxy();
		proxy.search();
	}
}


ProxyInovationHandler.java

package cn.sxt.dynamicproxy;

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

public class ProxyInovationHandler implements InvocationHandler{
	private Object target;//目標對象——真實對象
	public void setTarget(Object target) {
		this.target = target;
	}
	/*
	 * 生成代理類
	 */
	public Object getProxy() {
		return Proxy.newProxyInstance(this.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), this);
	}
	/*
	 * proxy是代理類
	 * method 代理類的調用處理程序的方法對象
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) 
			throws Throwable {
		log(method.getName());
		Object result =method.invoke(target, args);
		return result;
	}
	public void log(String methodName) {
		System.out.println("執行"+methodName+"方法");
	}
}

到這裏動態代理就完成了.

一個動態代理一般代理某一類業務,一個動態代理可以代理多個類。


Client.java

package cn.sxt.dynamicproxy;

import java.util.ArrayList;
import java.util.List;

import cn.sxt.service.UserService;
import cn.sxt.service.UserServiceImpl;

public class Client {
	public static void main(String[] args) {
//		UserService userService=new UserServiceImpl();
//		ProxyInovationHandler pih =new ProxyInovationHandler();
//		pih.setTarget(userService);
//		UserService proxy =(UserService)pih.getProxy();
//		proxy.search();
		ProxyInovationHandler ph =new ProxyInovationHandler();
		ph.setTarget(new ArrayList());
		List list =(List)ph.getProxy();
		list.add("hello");
		}
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章