結構型模式-代理模式
阿新 • • 發佈:2018-12-13
代理模式和裝飾器模式比較相似,都是對原有物件進行額外的操作,不同的是裝飾器是對原有物件的修飾,而代理模式是接手原物件的功能,並新增新的特性
先來看靜態代理的例子,使用者管理
package constructional.pattern.proxy.staticproxy; /*** * 使用者控制介面 * @author Administrator * */ public interface UserManager { public void addUser(String userId,String userName); public void modifyUser(String userId,String userName);public void delUser(String userId); public String findUser(String userId); }
package constructional.pattern.proxy.staticproxy; /**** * 使用者管理真正的實現類 * @author Administrator * */ public class UserManagerImpl implements UserManager { /***** * 新增使用者 */ public void addUser(String userId, String userName) { System.out.println("正在新增使用者,使用者為:"+userId+userName+"……"); } /***** * 刪除使用者 */ public void delUser(String userId) { System.out.println("delUser,userId="+userId); } /*** * 查詢使用者 */ public String findUser(String userId) { System.out.println("findUser,userId="+userId);return userId; } public void modifyUser(String userId, String userName) { System.out.println("modifyUser,userId="+userId); } }
package constructional.pattern.proxy.staticproxy; /*** * 代理類,提供使用者實現類的訪問控制 * @author Administrator * */ public class Proxy implements UserManager{ private UserManager userManager; public Proxy(UserManagerImpl ul) { userManager=ul; } public void addUser(String userId, String userName) { System.out.println("正在進行新增使用者前的準備工作,使用者id為:"+userId+"……"); try { userManager.addUser(userId, userName); System.out.println("成功新增使用者"+userId+",正在進行確認處理……"); } catch (Exception e) { System.out.println("新增,userId="+userId+"失敗!"); } } public void delUser(String userId) { // TODO Auto-generated method stub } public String findUser(String userId) { // TODO Auto-generated method stub return null; } public void modifyUser(String userId, String userName) { // TODO Auto-generated method stub } }
測試程式碼
package constructional.pattern.proxy.staticproxy; /**** * 客戶端 * @author Administrator * */ public class Client { public static void main(String []args) { UserManager userManager=new Proxy( new UserManagerImpl()); userManager.addUser("0001", "張三"); } }
執行結果
看完了靜態代理,再來看看動態代理,正常的動態代理
package constructional.pattern.proxy.dynamicproxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class LoginHandler2 implements InvocationHandler { private Object target; public LoginHandler2(Object target) { super(); this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("登入成功"); try { method.invoke(target, null); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return null; } }
package constructional.pattern.proxy.dynamicproxy; public class User implements UserMgr{ @Override public void addUser() { System.out.println("新增使用者"); } }
package constructional.pattern.proxy.dynamicproxy; public interface UserMgr { public void addUser(); }
測試程式碼
package constructional.pattern.proxy.dynamicproxy; import java.lang.reflect.Proxy; public class JdkTest2 { public static void main(String args[]){ User u = new User(); LoginHandler2 l = new LoginHandler2(u); ClassLoader c = ClassLoader.getSystemClassLoader(); try { UserMgr ur = (UserMgr)Proxy.newProxyInstance(c,new Class[]{UserMgr.class}, l); ur.addUser(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
執行結果
下面是手動編譯代理類的程式碼
package constructional.pattern.proxy.dynamicproxy; import java.lang.reflect.Method; public interface InvocationHandler { public void invoke(Object o,Method m); }
package constructional.pattern.proxy.dynamicproxy; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class LoginHandler implements InvocationHandler{ private Object target; public LoginHandler(Object target) { super(); this.target = target; } @Override public void invoke(Object o, Method m) { System.out.println("登入成功"); try { m.invoke(target, null); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
package constructional.pattern.proxy.dynamicproxy; public interface UserMgr { public void addUser(); }
package constructional.pattern.proxy.dynamicproxy; public class User implements UserMgr{ @Override public void addUser() { System.out.println("新增使用者"); } }
package constructional.pattern.proxy.dynamicproxy; import java.io.FileWriter; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; import java.util.Random; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class Proxy { public static Object getProxyInstance(Class inface,InvocationHandler h) throws Exception{ String rt ="\r\t"; byte[] bytes = new byte[1]; bytes[0] = 1; String className = "P" + Math.abs(new Random().nextLong()); String methodStr = ""; // for(Method m:inface.getMethods()){ // methodStr+=" @Override" + rt+ // " public void " + m.getName() + "(){" + rt + // " long startTime = System.currentTimeMillis();"+ rt + // " System.out.println(\"startTime:\"+startTime);"+ rt + // " t." + m.getName() + "()" + ";"+ rt + // " long endTime = System.currentTimeMillis();"+ rt + // " System.out.println(\"Time:\"+(endTime-startTime));"+ rt + // // " }" + rt; // // } for(Method m : inface.getMethods()) { methodStr += "@Override" + rt + "public void " + m.getName() + "() {" + rt + " try {" + rt + " Method md = " + inface.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt + " h.invoke(this, md);" + rt + " }catch(Exception e) {e.printStackTrace();}" + rt + "}"; } String str = "package constructional.pattern.proxy.dynamicproxy;"+ rt + "import java.lang.reflect.Method;" + rt + "public class " + className + "Proxy implements " +inface.getName()+ "{"+ rt + " constructional.pattern.proxy.dynamicproxy.InvocationHandler h;" + rt + " public " + className + "Proxy(InvocationHandler h) {"+ rt + " super();"+ rt + " this.h = h;"+ rt + "}"+ rt + methodStr+ "}"; String fileName =System.getProperty("user.dir")+"/src/constructional/pattern/proxy/dynamicproxy/" + className + "Proxy.java"; FileWriter fw = new FileWriter(fileName); fw.write(str); fw.flush(); fw.close(); //compile JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null); Iterable units = fileMgr.getJavaFileObjects(fileName); CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units); t.call(); fileMgr.close(); //load into memory and create an instance URL[] urls = new URL[]{(new URL("file:/"+System.getProperty("user.dir")+"/src/"))}; URLClassLoader ul = new URLClassLoader(urls); Class c = ul.loadClass("constructional.pattern.proxy.dynamicproxy." + className +"Proxy"); System.out.println(c); Constructor ctr = c.getConstructor(InvocationHandler.class); Object m = (Object)ctr.newInstance(h); return m; } }
測試類
package constructional.pattern.proxy.dynamicproxy; public class Test2 { public static void main(String args[]){ User u = new User(); LoginHandler l = new LoginHandler(u); try { UserMgr ur = (UserMgr)Proxy.getProxyInstance(UserMgr.class, l); ur.addUser(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
執行結果