有一個接口Person,裏面有一個方法run()html
package com.itzhouq.demo1; public interface Person { public void run(); }
類NormalPerson實現了這個接口Personjava
package com.itzhouq.demo1; public class NormalPerson implements Person { @Override public void run() { System.out.println("走......."); } }
因此建立一個類Superson繼承NormalPersonweb
package com.itzhouq.demo1; public class Superson extends NormalPerson { //重寫了父類NormalPerson的方法 @Override public void run() { super.run(); System.out.println("加強了,變成飛了。。。"); } }
package com.itzhouq.demo1; import org.junit.Test; /* * 加強一個對象的方法之一:繼承方式 */ public class Demo { @Test public void test() { NormalPerson p = new NormalPerson(); p.run();//走....... } //需求:對普通人的run方法進行加強,由走變成飛----加強一個對象的方法 //用繼承來實現需求:建立一個類繼承NormalPerson @Test public void test2() { Superson superson = new Superson(); superson.run(); // 走....... // 加強了,變成飛了。。。 } }
條件:面試
接口:app
package com.itzhouq.demo2; public interface Person { public void run(); }
須要被加強的方法run()jsp
package com.itzhouq.demo2; public class NormalPerson implements Person { @Override public void run() { System.out.println("走......."); } }
建立一個裝飾者類,實現run()所在類,實現的接口Personide
package com.itzhouq.demo2; public class Superson implements Person { //被裝飾者的引用 private NormalPerson p; public Superson(NormalPerson p) { this.p = p; } @Override public void run() { //這個是被裝飾者之前的方法 p.run(); //加強 System.out.println("加強了,變成飛。。。。"); } }
package com.itzhouq.demo2; import org.junit.Test; /* * 加強一個對象的方法之二:裝飾者方式 */ public class Demo { @Test public void test() { NormalPerson p = new NormalPerson(); p.run();//走....... } //需求:對普通人的run方法進行加強,由走變成飛 //僞裝不知道接口的實現類NormalPerson,可是要對普通人的run方法進行加強 //不知道實現類就沒法使用繼承的方式進行加強 //使用裝飾者解決這樣的問題: //條件1:裝飾者()和被裝飾者()實現同一個接口Person //條件2:裝飾者裏面有被裝飾者的引用 在我出生的時候,你把你給我,我對你進行加強 @Test public void test2() { NormalPerson p = new NormalPerson(); Superson superson = new Superson(p); superson.run(); // 走....... // 加強了,變成飛。。。。 } }
動態代理的條件:必須知道要被代理的類/對象是誰,這裏要被代理的類是NoemalPersonpost
Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interface, InvocationHander h); //返回一個指定接口的代理類實現
接口person,這裏再加一個方法sleep測試
package com.itzhouq.demo3; public interface Person { public void run(); public String sleep(); }
實現類NomalPersonthis
package com.itzhouq.demo3; public class NormalPerson implements Person { @Override public void run() { System.out.println("走......."); } @Override public String sleep() { System.out.println("睡覺了。。。"); return "sleep"; } }
package com.itzhouq.demo3; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import org.junit.Test; public class Demo { @Test public void test() { NormalPerson p = new NormalPerson(); p.run();//走....... } //需求:使用動態代理的方式對普通人進行加強 //JDK提供的類和方法能夠給我們動態的生成代理對象/加強對象 /* * 參數概述:固定的 * 參數1:和要被加強的對象,同樣的,類加載器 * 參數2:和要被加強的對象同樣的接口 * 1 根據指定的傳遞接口返回一個該接口下的實例 * 2 傳遞的接口裏面的方法就是能夠被加強的全部方法 * 參數3:全部的加強業務的邏輯實現(方法) */ @Test public void test1() { NormalPerson p = new NormalPerson(); Person proxyPerson = (Person) Proxy.newProxyInstance( p.getClass().getClassLoader(), p.getClass().getInterfaces(), new InvocationHandler() { /* * 參數概述:固定的 * 參數1:不用管,永遠是固定值 代理對象的類型 * 參數2:要被加強的方法 * 參數3:要被加強的方法運行過程當中須要的參數 */ @Override //invoke裏面是全部的加強業務的邏輯代碼 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //讓之前的方法執行 //參數1:自己應該執行這個方法的對象 //參數2:執行這個方法須要的參數 Object value = method.invoke(p, args); //原來方法的返回值 System.out.println(value); // 寫加強業務邏輯 System.out.println("加強了,變成飛了。。。"); //最終的返回值,誰調用返回給誰 return "abcd"; } }); proxyPerson.run();//執行接口中的每個須要加強的方法,invoke都會執行一遍,執行的內容就是針對該方法的加強 // 走....... // 加強了,變成飛了。。。 String value = proxyPerson.sleep(); System.out.println(value); // 睡覺了。。。 // sleep // 加強了,變成飛了。。。 // abcd } }
JSP
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Insert title here</title> </head> <body> <form action="${pageContext.request.contextPath }/sd1" method="get"> 用戶名:<input type="text" name="username"> <input type="submit" value="提交"> </form> <hr> <form action="${pageContext.request.contextPath }/sd1" method="post"> 用戶名:<input type="text" name="username"> <input type="submit" value="提交"> </form> </body> </html>
Servlet
package com.itzhouq.web; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class ServletDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); System.out.println(username); } public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
web.xml
<filter> <filter-name>MyFilter</filter-name> <filter-class>com.itzhouq.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
MyFilter
package com.itzhouq.filter; import java.io.IOException; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; public class MyFilter implements Filter { public MyFilter() { } public void destroy() { } public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) throws IOException, ServletException { //要加強的方法:request.getparameter //被代理的對象:request HttpServletRequest request = (HttpServletRequest)req; //動態的生成代理對象 HttpServletRequest hsr = (HttpServletRequest) Proxy.newProxyInstance( request.getClass().getClassLoader(), request.getClass().getInterfaces(), new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //1. 判斷是不是要加強的方法getParameter if("getParameter".equals(method.getName())) { //知道getParameter使用的是哪一個提交方式 String m = request.getMethod(); //判斷是get仍是post if("get".equalsIgnoreCase(m)) { // 之前方法調用後的亂碼 String s = (String)method.invoke(request, args); // 加強---解決亂碼 s = new String(s.getBytes("iso8859-1"),"utf-8"); return s; } if("post".equalsIgnoreCase(m)) { request.setCharacterEncoding("utf-8"); return method.invoke(request, args); } } // 若是是別的方法 return method.invoke(request, args); } }); chain.doFilter(hsr, response); } public void init(FilterConfig fConfig) throws ServletException { } }