摘要:經(jīng)過(guò)前面幾次反射機(jī)制的學(xué)習(xí),這次用反射的知識(shí)寫(xiě)一個(gè)類似于框架處理機(jī)制的小。和在引入反射知識(shí)前,先簡(jiǎn)單介紹下框架和。再次使用反射獲取的最新值,組成返回,同時(shí)根據(jù)方法的返回值,去中獲取對(duì)應(yīng)的。最后根據(jù)的返回值和的名稱組成最終展示的視圖。
經(jīng)過(guò)前面幾次反射機(jī)制的學(xué)習(xí),這次用反射的知識(shí)寫(xiě)一個(gè)類似于Struts框架處理機(jī)制的小demo。
Servlet 和 Sturts在引入反射知識(shí)前,先簡(jiǎn)單介紹下Sturts框架和Servlet。
在沒(méi)有一些Web框架之前,當(dāng)我們要寫(xiě)Java Web應(yīng)用使用的就是Servlet。一個(gè)簡(jiǎn)單的Servletdemo就是如下所示。
public class HelloWorld extends HttpServlet { private String message; public void init() throws ServletException { message = "Hello World"; } public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("" + message + "
"); } public void destroy() { } }
servlet會(huì)提供出來(lái)doGet和doPost,同時(shí)接收用戶傳入的參數(shù),進(jìn)行業(yè)務(wù)處理,再返回視圖。那么Servlet如何與URL對(duì)應(yīng)起來(lái)呢,答案就是在web.xml,綁定servlet和url之間的映射關(guān)系。
HelloWorld HelloWorld HelloWorld /HelloWorld
映射、業(yè)務(wù)邏輯處理、視圖返回全部在servlet中完成,耦合度比較高,隨著url的增多,servlet會(huì)越來(lái)越多,需要在web.xml配置很多映射關(guān)系,不利于維護(hù)。同時(shí)servlet的入?yún)⒁约胺祷氐膮?shù)很依賴于當(dāng)前運(yùn)行的容器,本身也是線程不安全的,當(dāng)入?yún)⒎浅6鄷r(shí),需要多次調(diào)用getParm方法,代碼很冗余。
之后Struts框架誕生,通過(guò)統(tǒng)一的ActionServlet處理具體的url請(qǐng)求和參數(shù)映射以及根據(jù)不同的返回結(jié)果跳轉(zhuǎn)不同的視圖,開(kāi)發(fā)者只需要關(guān)心自己的業(yè)務(wù)邏輯,就可以實(shí)現(xiàn)web應(yīng)用的開(kāi)發(fā)。具體的Struts的配置文件,大致如下面XML所示。
/jsp/homepage.jsp /jsp/showLogin.jsp /jsp/welcome.jsp /jsp/error.jsp
我們只需要分別實(shí)現(xiàn)視圖和業(yè)務(wù)邏輯,再通過(guò)struts將他們綁定起來(lái),就可以完成開(kāi)發(fā)工作,也更便于理解,方便維護(hù)。有興趣的讀者可以自行深入學(xué)習(xí)下servlet和struts的思想。
小demo我想寫(xiě)的小demo就是利用讀取xml,利用反射加載不同的action,進(jìn)行業(yè)務(wù)邏輯處理,最后輸出返回的視圖,整個(gè)邏輯思路還是比較簡(jiǎn)單,純當(dāng)反射學(xué)習(xí)的練手。
首先是定義配置類,把xml中action對(duì)應(yīng)的映射關(guān)系保存下來(lái)
private class ActionConfig { private String name; private String className; private MapviewResult = new HashMap<>();
當(dāng)初始化讀取xml完畢后,得到如下結(jié)構(gòu),action的名字對(duì)應(yīng)著具體的action配置
MapactionConfigMap = new HashMap<>();
模擬Struts ActionServlet的運(yùn)作方式
public View runAction(String actionName, Mapparams) { String className = cfg.getClassName(actionName); if (className == null) { return null; } try { Class> clz = Class.forName(className); Object action = clz.newInstance(); ReflectionUtil.invokeSetMethods(action, params); String resultName = (String) clz.getDeclaredMethod("execute").invoke(action); Map result = ReflectionUtil.invokeGetMethods(action); String resultView = cfg.getViewResult(actionName, resultName); return new View(resultView, result);
通過(guò)actionName從配置類中拿到具體的執(zhí)行類的全類名,其實(shí)Struts框架就是直接解析url,然后對(duì)應(yīng)到xml配置的對(duì)應(yīng)action名稱,將url和具體的執(zhí)行類綁定在一起。
之后是使用Class.forName創(chuàng)建類類型,然后創(chuàng)建對(duì)應(yīng)的實(shí)例。ReflectionUtil里面做的事情就是,先獲取action中對(duì)應(yīng)的field的Name,然后從變量中,根據(jù)filed名稱找對(duì)應(yīng)的值,然后使用set方法對(duì)action的field進(jìn)行賦值操作,就是LoginAction中的相關(guān)信息。
public class LoginAction { private String name; private String password; private String message;
這一步就省去了使用servlet時(shí),重復(fù)去get賦值的繁瑣操作,利用反射機(jī)制,直接對(duì)成員變量進(jìn)行賦值,開(kāi)發(fā)者只需要將前端會(huì)傳入的參數(shù)名稱和后端類中的名稱做好事先的確認(rèn)即可。
然后就是通過(guò)反射調(diào)用execute方法,使用了Method.invoke方法。再次使用反射獲取field的最新值,組成map返回,同時(shí)根據(jù)方法的返回值,去actionConfigMap中獲取對(duì)應(yīng)的view。
最后根據(jù)field的返回值map和view的名稱組成最終展示的視圖。
以上其實(shí)就是根據(jù)反射知識(shí)模仿的struts核心運(yùn)行流程的小demo,整個(gè)web框架處理了非常多的其他的事情比如參數(shù)映射,安全,Json處理等,如果有興趣,可以進(jìn)一步做學(xué)習(xí)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/70760.html
摘要:分類根類加載器也被稱為引導(dǎo)類加載器,負(fù)責(zé)核心類的加載比如等。要想解剖一個(gè)類必須先要獲取到該類的字節(jié)碼文件對(duì)象。 這是劉意老師的JAVA基礎(chǔ)教程的筆記講的賊好,附上傳送門 傳智風(fēng)清揚(yáng)-超全面的Java基礎(chǔ) 一、類的加載 1.類初始化的時(shí)機(jī) 創(chuàng)建類的實(shí)例訪問(wèn)類的靜態(tài)變量,或者為靜態(tài)變量賦值調(diào)用類的靜態(tài)方法使用反射方式來(lái)強(qiáng)制創(chuàng)建某個(gè)類或接口對(duì)應(yīng)的java.lang.Class對(duì)象初始化某個(gè)類...
摘要:反射機(jī)制一結(jié)合官方通過(guò)編寫(xiě)的反射教程,復(fù)習(xí)一下反射的知識(shí)。反射的概念反射是一種在運(yùn)行時(shí)獲取以及修改應(yīng)用行為的一種工具。因?yàn)榉瓷湫枰獎(jiǎng)討B(tài)的解析類的信息,相比于非反射使用的方式要慢。反射需要獲取一定的運(yùn)行時(shí)權(quán)限,在特定的安全環(huán)境下不一定存在。 Java反射機(jī)制(一) 結(jié)合Oracle官方通過(guò)JDK8編寫(xiě)的反射教程,復(fù)習(xí)一下反射的知識(shí)。結(jié)尾篇補(bǔ)一個(gè)小例子。 主要內(nèi)容 這次博客的主要內(nèi)容就是簡(jiǎn)...
摘要:再附一部分架構(gòu)面試視頻講解本文已被開(kāi)源項(xiàng)目學(xué)習(xí)筆記總結(jié)移動(dòng)架構(gòu)視頻大廠面試真題項(xiàng)目實(shí)戰(zhàn)源碼收錄 Java反射(一)Java反射(二)Java反射(三)Java注解Java IO(一)Java IO(二)RandomAccessFileJava NIOJava異常詳解Java抽象類和接口的區(qū)別Java深拷貝和淺拷...
摘要:本文是作者自己對(duì)中線程的狀態(tài)線程間協(xié)作相關(guān)使用的理解與總結(jié),不對(duì)之處,望指出,共勉。當(dāng)中的的數(shù)目而不是已占用的位置數(shù)大于集合番一文通版集合番一文通版垃圾回收機(jī)制講得很透徹,深入淺出。 一小時(shí)搞明白自定義注解 Annotation(注解)就是 Java 提供了一種元程序中的元素關(guān)聯(lián)任何信息和著任何元數(shù)據(jù)(metadata)的途徑和方法。Annotion(注解) 是一個(gè)接口,程序可以通過(guò)...
摘要:找到字節(jié)碼并創(chuàng)建一個(gè)對(duì)象。鏈接,檢驗(yàn)字節(jié)碼,為字段分配存儲(chǔ)空間,解決其對(duì)他類的引用。初始化,如果有父類則初始化父類,執(zhí)行靜態(tài)初始化器和靜態(tài)初始化區(qū)塊直到第一次訪問(wèn)靜態(tài)成員時(shí)初始化才執(zhí)行。如果成員不是編譯時(shí)常量由初始化器賦值,也會(huì)引起初始化。 有兩種形式在運(yùn)行時(shí)獲取類型信息: 傳統(tǒng)的RTTI 反射 Class對(duì)象 運(yùn)行時(shí)的類型信息是通過(guò)Class對(duì)象表現(xiàn)的,它包含了類的信息。所有...
閱讀 2079·2021-09-22 15:54
閱讀 1838·2021-09-04 16:40
閱讀 864·2019-08-30 15:56
閱讀 2630·2019-08-30 15:44
閱讀 2156·2019-08-30 13:52
閱讀 1129·2019-08-29 16:35
閱讀 3350·2019-08-29 16:31
閱讀 2570·2019-08-29 13:48