老師上課講的比較通俗易懂,總結記錄一下。java
以下圖,好比我須要去買一臺聯想電腦,可是聯想總部在北京,我人在西安,若是聯想公司在西安沒有代理經銷商,那我須要去北京總部購買,耗時耗力。可是若是聯想在你當地有設經銷商,那麼咱們須要購買筆記本這個需求,就變得很是簡單了,只須要去當地門店便可,應該很好理解了。設計模式
聯想公司它本身能夠生產電腦,也能夠本身銷售電腦,這就比如咱們建立的真是對象有兩個方法同樣,經銷商能夠賣電腦,可是他不能生產電腦,電腦從哪裏來?確定是從聯繫公司進貨,而後在銷售,這就至關於代理對象調用了真實對象生產電腦的方法。數組
同時代理對象能夠爲用戶提供真是對象完成它不能不了的動能,可能說到這裏,對於代理模式的一些基本認識就應該大體瞭解了,因此使用代理模式,簡而言之能夠加強對象的功能,而Java中所謂的23中設計模式,也就是一些通用的解決固定問題的方式。ide
代理模式的一些基本概念 spa
真實對象:被代理的對象設計
代理對象:代替真實對象的對象代理
代理模式:代理對象代理真實對象,達到加強真實對象功能的目的。 (理論性的東西,知道是什麼意思就好,沒必要糾結)code
代理模式實現方式有兩種對象
1. 靜態代理:有一個類文件描述代理模式blog
2. 動態代理:在內存中造成代理類 (動態代理相對靈活一些,使用動態代理比使用靜態代理對一些)
實現步驟:
加強方式:
簡單Demo
定義接口和方法
public interface SaleComputer { public String sale(double money); public void show(); }
這是你的真實對象
//真實的類 聯想公司 public class Lenovo implements SaleComputer { @Override public String sale(double money) { System.out.println("花了" + money + "買了一臺電腦"); return "聯想電腦"; } @Override public void show() { System.out.println("展現電腦 ..."); } }
這是你的代理對象
public class ProxyTest { public static void main(String[] args) { //1.建立真實對象 Lenovo lenovo = new Lenovo(); //2.傳遞三個參數, // 參數一: 類加載器 真實對象.getClass().getClassLoader() // 參數二: 接口數組 真實對象.lenovo.getClass().getInterfaces() // 參數三: 處理器 new InvocationHandler() SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() { /** * 代理邏輯編寫的方法:代理對象調用的全部方法都會被執行 * @param proxy 代理對象 * @param method 代理對象調用方法,被封裝爲的對象 * @param args 代理對象調用方式時,傳遞的實際參數 * @return * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { /* System.out.println("該方法被執行了"); System.out.println(method.getName()); System.out.println(args[0]); */ //加強參數 假設代理對象在真實對象拿貨只要市場價的85%,經銷商也要賺錢.那就須要修改原sale方法裏的參數了. if (method.getName().equals("sale")) { double money = (double) args[0]; //args[0]=8000 money = money * 0.85; //加強後參數money變爲6800 /* 使用真實對象調用該方法, Object obj = method.invoke(lenovo, args); 使用代理對象調用該方法, Object obj = method.invoke(lenovo, money); */ String obj = (String) method.invoke(lenovo, money); //還能夠加強方法體的邏輯:免費送貨 System.out.println("免費送貨上門"); //加強返回值,原方法只是返回一個電腦,如今還給你送點東西,本身理解哈,哈哈。 return obj+"_送你個鼠標墊"; } else { Object obj = method.invoke(lenovo, args); return obj; } } }); String computer = proxy_lenovo.sale(8000); System.out.println(computer); /* proxy_lenovo.show(); 沒有被加強,執行的話會原樣調用*/ } }
敏感詞彙過濾需求實現就用到了動態代理來加強方法
import javax.servlet.*; import javax.servlet.annotation.WebFilter; import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.ArrayList; import java.util.List; @WebFilter("/*") public class SensitiveWordsFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { //1.建立代理對象,加強getParameter方法 ServletRequest proxy_req = (ServletRequest) Proxy.newProxyInstance(req.getClass().getClassLoader(), req.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //加強getParameter方法 //判斷是不是getParameter方法 if (method.getName().equals("getParameter")) { //加強返回值 //獲取返回值 String value = (String) method.invoke(req, args); if (value != null) { for (String str : list) { if (value.contains(str)) { value = value.replaceAll(str, "***"); } } } return value; } //判斷方法名是不是 getParameterMap //判斷方法名是不是 getParameterValue return method.invoke(req, args); } }); //2.放行 chain.doFilter(proxy_req, resp); } private List<String> list = new ArrayList<String>();//敏感詞聚集合 public void init(FilterConfig config) throws ServletException { try { //1.獲取文件真實路徑 ServletContext servletContext = config.getServletContext(); String realPath = servletContext.getRealPath("/WEB-INF/classes/敏感詞彙.txt"); //2.讀取文件 BufferedReader br = new BufferedReader(new FileReader(realPath)); //3.將文件的每一行數據添加到list中 String line = null; while ((line = br.readLine()) != null) { list.add(line); } br.close(); System.out.println(list); } catch (Exception e) { e.printStackTrace(); } }
public void destroy() { } }