設計模式之代理模式淺析

     
/**
 * 代理模式:
 *   爲另外一個對象提供一個佔位符或者替身,以控制對這個對象的訪問
 * 
 * 按照控制方式的不一樣:
 *   遠程代理-->控制訪問遠程對象(不在同一個JVM的對象)
 *   虛擬代理-->控制訪問大開銷資源的對象(網絡或者IO對象)
 *   保護代理-->基於權限控制對資源的訪問(不一樣的權限,對資源的訪問層次不一樣)
 *   緩存代理-->爲開銷大的運算結果提供暫時的存儲
 *   智能引用代理-->當主題被引用時,進行額外的操做
 *   防火牆代理-->控制網絡資源的訪問
 *   同步代理-->在多線程的狀況下爲主題提供安全的訪問
 *   複雜隱藏代理-->用來隱藏一個類的複雜度並進行訪問控制
 *   寫入時複製代理-->用來控制對象的複製
 *   
 * 模式對比:
 *   裝飾者模式-->包裝一個對象,對其提供額外的功能
 *   適配器模式-->包裝一個對象,並提供不一樣的接口
 *   外觀模式-->包裝許多對象以提供訪問的簡單接口
 *   代理模式 -->包裝一個對象,以控制對它的訪問 
 *   
 *    
 *  示例:
 *    遠程代理使用RMI做爲示例 ,遠程訪問的還有EJB和WEBSERVICES
 *    虛擬代理使用網絡資源的加載做爲示例,利用JFRAME做爲示例
 *    保護代理使用資源的訪問做爲示例,像SPRING的AOP就用了保護代理   
 *    
 *    
 * 
 * @author Administrator
 *
 */



一、先看RMI示例的遠程代理java

   RMI參考以前的文章  http://blog.csdn.net/undergrowth/article/details/24913031緩存

  遠程服務接口安全

package com.undergrowth.proxy;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * 代理模式:
 *   爲另外一個對象提供一個佔位符或者替身,以控制對這個對象的訪問
 * 
 * 按照控制方式的不一樣:
 *   遠程代理-->控制訪問遠程對象(不在同一個JVM的對象)
 *   虛擬代理-->控制訪問大開銷資源的對象(網絡或者IO對象)
 *   保護代理-->基於權限控制對資源的訪問(不一樣的權限,對資源的訪問層次不一樣)
 *   緩存代理-->爲開銷大的運算結果提供暫時的存儲
 *   智能引用代理-->當主題被引用時,進行額外的操做
 *   防火牆代理-->控制網絡資源的訪問
 *   同步代理-->在多線程的狀況下爲主題提供安全的訪問
 *   複雜隱藏代理-->用來隱藏一個類的複雜度並進行訪問控制
 *   寫入時複製代理-->用來控制對象的複製
 *   
 * 模式對比:
 *   裝飾者模式-->包裝一個對象,對其提供額外的功能
 *   適配器模式-->包裝一個對象,並提供不一樣的接口
 *   外觀模式-->包裝許多對象以提供訪問的簡單接口
 *   代理模式 -->包裝一個對象,以控制對它的訪問 
 *   
 *    
 *  示例:
 *    遠程代理使用RMI做爲示例 ,遠程訪問的還有EJB和WEBSERVICES
 *    虛擬代理使用網絡資源的加載做爲示例,利用JFRAME做爲示例
 *    保護代理使用資源的訪問做爲示例,像SPRING的AOP就用了保護代理   
 *    
 *    
 * 
 * @author Administrator
 *
 */
public interface GumballMachineRemote extends Remote{
    /**
     * 每一個方法都必須拋出throws RemoteException異常 
     * @return
     * @throws RemoteException
     */
	public String getLocation() throws RemoteException;
	public int getCount() throws RemoteException;
	public String  getDescription() throws RemoteException;
	public State getCurrState() throws RemoteException;
	
}


遠程服務對象

package com.undergrowth.proxy;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
 * 遠程服務對象
 * @author Administrator
 *
 */
public class GumballMachine extends UnicastRemoteObject implements
		GumballMachineRemote {
	String location;
	String description;
	int count;
	State currentState;
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	/**
	 * 由於UnicastRemoteObject構造器須要處理異常 由於RMI在網絡上傳輸 會發生未知的異常
	 * 
	 * @throws RemoteException
	 */
	protected GumballMachine() throws RemoteException {
		super();
		// TODO Auto-generated constructor stub
	}

	public GumballMachine(String location, String description, int count) throws RemoteException {
		super();
		this.location = location;
		this.description = description;
		this.count = count;
		if(count>0){
			this.currentState = new NoMoneyState();
		}
		
	}

	@Override
	public String getLocation() {
		// TODO Auto-generated method stub
		return location;
	}

	@Override
	public int getCount() {
		// TODO Auto-generated method stub
		return count;
	}

	@Override
	public String getDescription() {
		// TODO Auto-generated method stub
		return description;
	}

	@Override
	public State getCurrState() {
		// TODO Auto-generated method stub
		return currentState;
	}

}


相關狀態

package com.undergrowth.proxy;

import java.io.Serializable;


/**
 * 使用RMI傳輸State 
 * @author Administrator
 *
 */
public interface State extends Serializable{
		public void insertMoney();
}

無幣狀態

package com.undergrowth.proxy;

/**
 * 模擬初始狀態
 * @author Administrator
 *
 */
public class NoMoneyState implements State {

	@Override
	public void insertMoney() {
		// TODO Auto-generated method stub
		System.out.println("投幣");
	}
	
}

RMI註冊服務和查找

package com.undergrowth.proxy;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
/**
 * RMI註冊服務和查找
 * @author Administrator
 *
 */
public class RegisterRmiServer {
	
	public static void registerRmi(int port,String name,GumballMachineRemote remoteServer){
		try {
			//建立register端口監聽
			LocateRegistry.createRegistry(port);
			//綁定服務
			Naming.rebind(name, remoteServer);
			//註冊遠程服務成功
			System.out.println("註冊遠程服務成功");
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public static GumballMachineRemote getRmiServer(String name){
		try {
			return (GumballMachineRemote) Naming.lookup(name);
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NotBoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return null;
	}
	
}

測試類

package com.undergrowth.proxy.test;

import static org.junit.Assert.*;

import java.rmi.RemoteException;

import javax.imageio.spi.RegisterableService;

import org.junit.Test;

import com.undergrowth.proxy.GumballMachine;
import com.undergrowth.proxy.GumballMachineRemote;
import com.undergrowth.proxy.RegisterRmiServer;

public class GumballMachineRemoteTest {

	@Test
	public void test() {
		try {
			//建立遠程服務
			GumballMachineRemote remoteServer=new GumballMachine("廣州蘿崗", "科學大道高德匯", 100);
			//綁定
			int port=4567;
			RegisterRmiServer.registerRmi(port,"rmi://192.168.1.101:"+port+"/remoteServer", remoteServer);
			//等待客戶端的查找RMI服務
			while(true){
				
			}
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	@Test
	public void testClient(){
		int port=4567;
		GumballMachineRemote remoteServer=RegisterRmiServer.getRmiServer("rmi://192.168.1.101:"+port+"/remoteServer");
		try {
			System.out.println(remoteServer.getCount());
			System.out.println(remoteServer.getLocation());
			System.out.println(remoteServer.getDescription());
			System.out.println(remoteServer.getCurrState());
		} catch (RemoteException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

}

先test(),而後testClient()

查看服務端口網絡



控制檯多線程

100
廣州蘿崗
科學大道高德匯
com.undergrowth.proxy.NoMoneyState@193a6a5


二、虛擬代理,使用JFRAME加載圖片組件,加載網絡資源,使用狀態模式管理圖片的狀態eclipse

面板ide

package com.undergrowth.proxy;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

/**
 * 虛擬代理-->用於代理大開銷的資源
 *   使用代理 在未加載資源時,顯示提示信息
 * @author Administrator
 *
 */
public class LoadImageUrlFrame extends JFrame {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	JMenu menu;
	JMenuBar menuBar;
	Map<String, String> imageResources = new HashMap<String, String>();
	ImageComponent imageComponent;

	public LoadImageUrlFrame() {

		initResources();

		menu = new JMenu("加載圖片");
		//添加菜單項
		addMenuItem(menu);
		menuBar = new JMenuBar();
		menuBar.add(menu);
		setJMenuBar(menuBar);
		
		//初始化圖片
		Icon icon=null;
		try {
			icon = new ImageProxy(new URL(imageResources.get("熊黛林")));
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//添加圖片組件
		imageComponent=new ImageComponent(icon);
		getContentPane().add(imageComponent);
		
		// 初始化操做
		setSize(800, 500);
		setLocation((getToolkit().getScreenSize().width-getWidth())/2, (getToolkit().getScreenSize().height-getHeight())/2);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

	/**
	 * 添加菜單項
	 * @param menu2
	 */
	private void addMenuItem(JMenu menu2) {
		// TODO Auto-generated method stub
		for (Iterator iterator = imageResources.keySet().iterator(); iterator.hasNext();) {
			String name = (String) iterator.next();
			//添加菜單項
			JMenuItem menuItem=new JMenuItem(name);
			menuItem.addActionListener(new ActionListener() {
				
				@Override
				public void actionPerformed(ActionEvent e) {
					// TODO Auto-generated method stub
					//當點擊菜單項的時候
					//替換圖片組件中的圖片 並將frame重繪
					try {
						//替換圖像組件中的圖片
						imageComponent.setIcon(new ImageProxy(new URL(imageResources.get(e.getActionCommand()))));
						//重繪面板
						repaint();
					} catch (MalformedURLException e1) {
						// TODO Auto-generated catch block
						e1.printStackTrace();
					}
				}
			});
			menu2.add(menuItem);
		}
	}

	/**
	 * 初始化圖片資源
	 */
	private void initResources() {
		// TODO Auto-generated method stub
		imageResources
				.put("古力娜扎",
						"http://cdn.duitang.com/uploads/item/201207/27/20120727130449_hSxQk.jpeg");
		imageResources.put("熊黛林",
				"http://ent.shangdu.com/stardata/P_5962597_1__1869907784.jpg");

	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		LoadImageUrlFrame frame = new LoadImageUrlFrame();

	}

}

圖片組件

package com.undergrowth.proxy;

import java.awt.Graphics;

import javax.swing.Icon;
import javax.swing.JComponent;

public class ImageComponent extends JComponent {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	Icon icon;
	public ImageComponent(Icon icon){
		this.icon=icon;
	}
	
	
	/**
	 * 繪製圖片組件
	 */
	@Override
	protected void paintComponent(Graphics g) {
		// TODO Auto-generated method stub
		super.paintComponent(g);
		int x=icon.getIconWidth();
		int y=icon.getIconHeight();
		x=(800-x)/2;
		y=(500-y)/2;
		icon.paintIcon(this, g, x, y);
	}



	public void setIcon(Icon icon) {
		this.icon = icon;
	}
	
	
	
}

圖片代理

package com.undergrowth.proxy;

import java.awt.Component;
import java.awt.Graphics;
import java.net.URL;

import javax.swing.Icon;
import javax.swing.ImageIcon;

public class ImageProxy implements Icon {

	ImageIcon icon;
	//圖像的狀態  使用狀態模式 在加載與未加載之間切換
	ImageState imageLoadState;
	ImageState imageNonLoadState;
	ImageState imageCurr;
	//代理圖片的位置
	URL imageUrl;
	public ImageProxy(URL imageUrl){
		this.imageUrl=imageUrl;
		imageNonLoadState=new ImageNonLoadState(this);
		imageLoadState=new ImageLoadState(this);
		imageCurr=imageNonLoadState;
	}
	
	/**
	 * 委託給當前狀態進行處理
	 */
	@Override
	public void paintIcon(Component c, Graphics g, int x, int y) {
		// TODO Auto-generated method stub
		imageCurr.paintIcon(c, g, x, y);
	}

	@Override
	public int getIconWidth() {
		// TODO Auto-generated method stub
		return imageCurr.getIconWidth();
	}

	@Override
	public int getIconHeight() {
		// TODO Auto-generated method stub
		return imageCurr.getIconHeight();
	}


	public ImageState getImageCurr() {
		return imageCurr;
	}


	public void setImageCurr(ImageState imageCurr) {
		this.imageCurr = imageCurr;
	}


	public ImageState getImageLoadState() {
		return imageLoadState;
	}


	public ImageState getImageNonLoadState() {
		return imageNonLoadState;
	}


	public ImageIcon getIcon() {
		return icon;
	}


	public void setIcon(ImageIcon icon) {
		this.icon = icon;
	}


	public URL getImageUrl() {
		return imageUrl;
	}

}

圖片狀態接口

package com.undergrowth.proxy;

import javax.swing.Icon;
/**
 * 圖像狀態接口
 * @author Administrator
 *
 */
public interface ImageState extends Icon{
	
}

圖片已加載狀態

package com.undergrowth.proxy;

import java.awt.Component;
import java.awt.Graphics;

public class ImageLoadState implements ImageState {

	ImageProxy imageProxy;
	
	
	public ImageLoadState(ImageProxy imageProxy) {
		super();
		this.imageProxy = imageProxy;
	}

	@Override
	public void paintIcon(Component c, Graphics g, int x, int y) {
		// TODO Auto-generated method stub
		imageProxy.getIcon().paintIcon(c, g, x, y);
	}

	@Override
	public int getIconWidth() {
		// TODO Auto-generated method stub
		return imageProxy.getIcon().getIconWidth();
	}

	@Override
	public int getIconHeight() {
		// TODO Auto-generated method stub
		return imageProxy.getIcon().getIconHeight();
	}

}


圖片未加載狀態學習

package com.undergrowth.proxy;

import java.awt.Component;
import java.awt.Graphics;

import javax.swing.ImageIcon;

public class ImageNonLoadState implements ImageState {

	ImageProxy imageProxy;
	public ImageNonLoadState(ImageProxy imageProxy){
		this.imageProxy=imageProxy;
	}
	
	@Override
	public void paintIcon(final Component c, Graphics g, int x, int y) {
		// TODO Auto-generated method stub
		g.drawString("正在加載圖片中。。。", x, y);
		//使用線程 加載網絡資源 加載完成後 重繪面板
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				//修改圖片狀態
				imageProxy.setIcon(new ImageIcon(imageProxy.getImageUrl()));
				imageProxy.setImageCurr(imageProxy.getImageLoadState());
				//重繪
				c.repaint();
			}
		}).start();
	}

	@Override
	public int getIconWidth() {
		// TODO Auto-generated method stub
		return 400;
	}

	@Override
	public int getIconHeight() {
		// TODO Auto-generated method stub
		return 400;
	}

}

測試 運行面板



三、保護代理,用於控制權限訪問測試

代理者與被代理者的共同接口ui

package com.undergrowth.proxy;

/**
 * Person接口 用於代理和被代理的共同接口
 * 用於實例保護代理
 * @author Administrator
 *
 */
public interface Person {
	public String getName() ;
	public void setName(String name) ;
	public String getHobby();
	public void setHobby(String hobby) ;
	public String getDescription() ;
	public void setDescription(String description);
	public float getScore() ;
	public void setScore(float score) ;
}
被代理者

package com.undergrowth.proxy;

/**
 * 每一個人均可以維護本身的信息 可是評分不能本身維護 須要別人維護
 * @author Administrator
 *
 */
public class PersonBeanImpl implements Person{

	String name;
	String hobby;
	String description;
	float score;
	
	
	
	public PersonBeanImpl(String name, String hobby, String description) {
		super();
		this.name = name;
		this.hobby = hobby;
		this.description = description;
		this.score = 0;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getHobby() {
		return hobby;
	}
	public void setHobby(String hobby) {
		this.hobby = hobby;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public float getScore() {
		return score;
	}
	public void setScore(float score) {
		this.score = score;
	}
	
	@Override
	public String toString() {
		return "PersonBean [name=" + name + ", hobby=" + hobby
				+ ", description=" + description + ", score=" + score + "]";
	}
	
	
}

代理工廠

package com.undergrowth.proxy;

import java.lang.reflect.Proxy;

/**
 * 簡單工廠  
 * 利用JDK內置的代理 建立代理對象
 * @author Administrator
 *
 */
public class ProxyFactory {
	
	public static Person getOwnerPersonBean(Person personBean){
		return (Person) Proxy.newProxyInstance(personBean.getClass().getClassLoader(), personBean.getClass().getInterfaces(), new PersonBeanOwnerHandler(personBean));
	}
	
	public static Person getNonOwnerPersonBean(Person personBean){
		return (Person) Proxy.newProxyInstance(personBean.getClass().getClassLoader(), personBean.getClass().getInterfaces(), new PersonBeanNonOwnerHandler(personBean));
	}
	
}

擁有者,事件處理者

package com.undergrowth.proxy;

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

/**
 * 本身處理器(擁有者) 本身能夠維護本身的信息 除了評分之外
 * @author Administrator
 *
 */
public class PersonBeanOwnerHandler implements InvocationHandler {

	Person personBean;
	
	
	public PersonBeanOwnerHandler(Person personBean) {
		super();
		this.personBean = personBean;
	}


	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		if(method.getName().startsWith("get")){//獲取本身的其餘信息
			return method.invoke(personBean, args);
		}else if(method.getName().equals("setScore")){
			throw new IllegalAccessException("你不能本身給本身評分");
		}else if(method.getName().startsWith("set")){ //設置本身的其餘信息
			return method.invoke(personBean, args);
		}
		return null;
	}

}


非擁有者

package com.undergrowth.proxy;

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

/**
 * 不是本身處理器(非擁有者) 能夠獲取信息 能夠設置其餘人的評分 可是不能設置其餘人的其餘信息
 * @author Administrator
 *
 */
public class PersonBeanNonOwnerHandler implements InvocationHandler {

	Person personBean;
	
	
	public PersonBeanNonOwnerHandler(Person personBean) {
		super();
		this.personBean = personBean;
	}


	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		if(method.getName().startsWith("get")){
			return method.invoke(personBean, args);
		}else if (method.getName().equals("setScore")) {
			return method.invoke(personBean, args);
		}else if (method.getName().startsWith("set")) {
			throw new IllegalAccessException("你不能設置其餘人的其餘信息");
		}
		return null;
	}

}

測試

package com.undergrowth.proxy.test;

import static org.junit.Assert.*;

import java.lang.reflect.InvocationHandler;

import org.junit.Test;

import com.undergrowth.proxy.Person;
import com.undergrowth.proxy.PersonBeanImpl;
import com.undergrowth.proxy.PersonBeanOwnerHandler;
import com.undergrowth.proxy.ProxyFactory;

public class PersonBeanTest {

	@Test
	public void test() {
		PersonBeanImpl personBean = new PersonBeanImpl("科比", "籃球", "職業素養最好的運動員");
		System.out.println(personBean);
		//建立擁有者
		Person personBeanOwner = ProxyFactory.getOwnerPersonBean(personBean);
		System.out.println(personBeanOwner.getName());
		personBeanOwner.setDescription(personBeanOwner.getDescription()
				+ ",老將中的戰鬥機");
		System.out.println(personBeanOwner.getDescription());
		System.out.println(personBean);
		try {
			// 本身給本身評分 會發生異常
			personBeanOwner.setScore(100);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			System.out.println(personBean);
		}
		//建立非擁有者
		Person personNonOwner=ProxyFactory.getNonOwnerPersonBean(personBean);
		System.out.println(personNonOwner.getDescription());
		personNonOwner.setScore(100);
		System.out.println(personBean);
		try {
			//設置別人的信息 會發生異常
			personNonOwner.setDescription("足球踢得很是好");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			System.out.println(personBean);
		}
	}

}

控制檯

PersonBean [name=科比, hobby=籃球, description=職業素養最好的運動員, score=0.0]
java.lang.reflect.UndeclaredThrowableException
	at $Proxy4.setScore(Unknown Source)
	at com.undergrowth.proxy.test.PersonBeanTest.test(PersonBeanTest.java:29)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
科比
職業素養最好的運動員,老將中的戰鬥機
PersonBean [name=科比, hobby=籃球, description=職業素養最好的運動員,老將中的戰鬥機, score=0.0]
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalAccessException: 你不能本身給本身評分
	at com.undergrowth.proxy.PersonBeanOwnerHandler.invoke(PersonBeanOwnerHandler.java:29)
	... 25 more
PersonBean [name=科比, hobby=籃球, description=職業素養最好的運動員,老將中的戰鬥機, score=0.0]
職業素養最好的運動員,老將中的戰鬥機
PersonBean [name=科比, hobby=籃球, description=職業素養最好的運動員,老將中的戰鬥機, score=100.0]
java.lang.reflect.UndeclaredThrowableException
	at $Proxy4.setDescription(Unknown Source)
	at com.undergrowth.proxy.test.PersonBeanTest.test(PersonBeanTest.java:42)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:601)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: java.lang.IllegalAccessException: 你不能設置其餘人的其餘信息
	at com.undergrowth.proxy.PersonBeanNonOwnerHandler.invoke(PersonBeanNonOwnerHandler.java:31)
	... 25 more
PersonBean [name=科比, hobby=籃球, description=職業素養最好的運動員,老將中的戰鬥機, score=100.0]



  以上便是遠程代理、虛擬代理、保護代理的示例代碼,代理模式的應用點太多了,後續遇到或者學習到,持續更新中,記錄學習的腳步

相關文章
相關標籤/搜索