1. 程式人生 > >動手實現一個簡單的java web框架

動手實現一個簡單的java web框架

最近看了《架構探險》這本書,實現了一個簡單的web框架,現在回顧一下完成這個框架的過程是怎麼樣的。

一、預備知識

(一)框架和類庫

首先通過框架和類庫的區別來理解一下框架,比如我們寫程式就像是建造一個房子,框架就像是房子的整體結構(由鋼筋水泥鑄成),我們只需要按照自己的需要去裝修自己的房子,讓它成為我們想要的樣子,而類庫就像是我們需要用到的一個個材料,比如門板、玻璃、塗料,我們用這些材料來裝修裝修。我們使用框架和類庫,就可以很快的構建好一個房子。
使用框架,其實是框架最終呼叫我們寫的程式,根據我們寫的配置、註解這些,動態的生成我們需要的東西,那麼其中必然要用到反射和註解。

(二)java反射

框架能夠在不改變程式碼的情況下,根據程式設計師的不同配置,去做不同的事情,這種動態執行的方式就是反射的一個應用。那麼,什麼叫反射呢?
JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意方法和屬性;這種動態獲取資訊以及動態呼叫物件方法的功能稱為java語言的反射機制。(來自百度百科)
還有一種說法:反射就是把java類中的各種成分對映成相應的java類。所有的java類都有共同的特性,比如都是一個類,都有建構函式、成員變數、成員方法,那麼就可以把這些相同的部分抽象成一個類,形成Class類、Constructor類、Field類、Method類。根據Class類就可以獲取類的資訊、根據Constructor類就可以例項化對應類…
具體的反射講解可以看其他的部落格,我這兒只列舉用到的比較多的幾個api:

學習java.lang.Class類和java.lang.reflect包下面的類
(1)Class類:
// 返回與帶有給定字串名的類或介面相關聯的 Class 物件。
static Class<?> forName(String className) 
//建立此 Class 物件所表示的類的一個新例項。
T   newInstance() 
// 如果指定型別的註釋存在於此元素上,則返回 true,否則返回 false。
 boolean    isAnnotationPresent(Class<? extends Annotation> annotationClass)          
 (2
)Constructor類 //使用此 Constructor 物件表示的構造方法來建立該構造方法的宣告類的新例項,並用指定的初始化引數初始化該例項。 T newInstance(Object... initargs) (3)Method類: //對帶有指定引數的指定物件呼叫由此 Method 物件表示的底層方法。 Object invoke(Object obj, Object... args) (2)Field類 // 將指定物件變數上此 Field 物件表示的欄位設定為指定的新值。 void set(Object obj, Object value)

(三)java註解

框架中我們一般都會用到很多註解,所以註解的知識肯定是必不可少的。
定義:註解(Annotation),也叫元資料。一種程式碼級別的說明。它是JDK1.5及以後版本引入的一個特性,與類、介面、列舉是在同一個層次。它可以宣告在包、類、欄位、方法、區域性變數、方法引數等的前面,用來對這些元素進行說明,註釋。
分類:jdk自帶註解、自定義註解。
自帶註解有以下三個:

@Override,表示當前的方法定義將覆蓋超類中的方法。
@Deprecated,表示下面的程式碼是不贊成使用的,被棄用的程式碼。
@SuppressWarnings,關閉不當編譯器警告資訊。

自定義註解如下:

import java.lang.annotation.*;
//以下四行為元註解:註解的註解
@Documented                         //儲存在javadoc中
@Inherited                          //允許被子類繼承父類中的註解
@Target(ElementType.METHOD)         //註解定義在方法上
@Retention(RetentionPolicy.RUNTIME) //註解保留到執行時
public @interface Action {
    //請求型別和路徑
    String value();
}

一般自定義註解的使用模式:
註解定義——註解使用——註解解析(利用反射)
學習註解時,主要學習以下的類:
java.lang.annotation包

(四)代理技術

一般框架中的aop特性就是通過動態代理技術來實現的。所以有必要先搞清楚代理技術。

1.代理模式

代理模式意圖:為其他物件提供一種代理以控制對這個物件的訪問。
可以詳細控制訪問某個類(物件)的方法,在呼叫這個方法前作的前置處理(統一的流程程式碼放到代理中處理)。呼叫這個方法後做後置處理。
例如:明星的經紀人,租房的中介等等都是代理

2.靜態代理

結構圖:
代理模式

2
靜態代理模式一般會有三個角色:

抽象角色:指代理角色(經紀人)和真實角色(明星)對外提供的公共方法,一般為一個介面

真實角色:需要實現抽象角色介面,定義了真實角色所要實現的業務邏輯,以便供代理角色呼叫。也就是真正的業務邏輯在此。

代理角色:需要實現抽象角色介面,是真實角色的代理,通過真實角色的業務邏輯方法來實現抽象方法,並可以附加自己的操作。 將統一的流程控制都放到代理角色中處理!

例子:
類結構:
類列表

  • Subject類:抽象角色
//抽象角色
public interface Subject {
    void request();
}
  • RealSubject類:真實角色(目標角色,要被代理的目標)
//真實角色
public class RealSubject implements Subject {
    @Override
    public void request() {
        System.out.println("do request");
    }
}
  • SubjectProxy類:代理角色
//代理角色
public class SubjectProxy implements Subject {
    private RealSubject realSubject;

    public SubjectProxy(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public void request() {
        before();                   //新增前置附加操作
        realSubject.request();      //執行真實角色的方法
        after();                    //新增後置附加操作
    }

    private void before(){
        System.out.println("before");
    }

    private void after(){
        System.out.println("after");
    }
}
  • Client類:客戶端
public class Client {
    public static void main(String[] args) {
        Subject subject = new SubjectProxy(new RealSubject());
        subject.request();
    }
}
  • 執行結果
before
do request
after

3.JDK動態代理

jdk動態代理需瞭解兩個類:java.lang.reflect.Proxy類 和 java.lang.reflect.InvocationHandler介面。

java.lang.reflect.Proxy類
//返回一個指定介面的代理類例項,該介面可以將方法呼叫指派到指定的呼叫處理程式。
static Object   newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 
/*注意這三個引數:loader是類載入器,interfaces是需要實現的介面,h就是指定的呼叫處理程式。當我們知道了一個介面有哪些方法,它的類載入器是誰,我們就能通過反射構造出一個相應的代理類來。 */

java.lang.reflect.InvocationHandler介面
//在代理例項上處理方法呼叫並返回結果。 
Object  invoke(Object proxy, Method method, Object[] args) 
/*這個方法就是我們在呼叫目標類的方法時,實際執行的方法(代理類的方法),我們只要在這個方法中加入我們需要額外加上的功能就可以了。  */                 

程式碼例項
類結構:
jdk動態代理

  • Hello介面:抽象角色
public interface Hello {
    void say(String name);
}
  • HelloImpl類:真實角色(被代理類)
public class HelloImpl implements Hello {
    //業務邏輯
    public void say(String name) {
        System.out.println("hello " + name);
    }
}
  • ProxyHandler類:代理類的處理程式類
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ProxyHandler implements InvocationHandler {
    private Object target;
    public ProxyHandler(Object target){
        this.target = target;
    }

    //真正執行的代理方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        before();
        Object obj = method.invoke(target, args);
        after();
        return obj;
    }

    private void before(){
        System.out.println("before");
    }

    private void after(){
        System.out.println("after");
    }


}
  • Client類:客戶端

import java.lang.reflect.Proxy;

public class Client {
    public static void main(String[] args) {

        ProxyHandler handler = new ProxyHandler(new HelloImpl());

        Hello helloProxy = (Hello) Proxy.newProxyInstance(
                HelloImpl.class.getClassLoader(),           //被代理類的類載入器
                HelloImpl.class.getInterfaces(),            //被代理類要實現的介面
                handler                                     //被代理類關聯的呼叫處理程式
        );

        helloProxy.say("bobo");
    }
}
  • 執行結果
before
hello bobo
after

4.CGLib動態代理

(五)其他

1.使用過框架,只有用過了之後再去探索如何實現框架。
2.最好會使用git,maven。

二、框架實現

(一)整體設計

(二)實現IOC特性

(三)實現MVC

(四)實現AOP特性

相關推薦

動手實現一個簡單的 rpc 框架到入門 grpc (上)

rpc 全稱 `Remote Procedure Call` 遠端過程呼叫,即呼叫遠端方法。我們呼叫當前程序中的方法時很簡單,但是想要呼叫不同程序,甚至不同主機、不同語言中的方法時就需要藉助 rpc 來實現,下面我一步步實現一個簡單的 rpc 呼叫。 server 端註冊函式,執行並接收客戶端請求 ```

動手實現一個簡單的 rpc 框架到入門 grpc (下)

之前手動實現了一次簡陋的 rpc 呼叫,為了簡單使用了 json 編碼資訊,其實這是非常不可靠的,go 中 json 解析會有一些問題,比如整數會變成浮點數,而且 json 字串比較佔空間。 gRPC 由 google 開發,是一款語言中立、平臺中立、開源的 RPC 框架,預設使用 protocol buf

動手實現一個簡單java web框架

最近看了《架構探險》這本書,實現了一個簡單的web框架,現在回顧一下完成這個框架的過程是怎麼樣的。 一、預備知識 (一)框架和類庫 首先通過框架和類庫的區別來理解一下框架,比如我們寫程式就像是建造一個房子,框架就像是房子的整體結構(由鋼筋水泥鑄成),我

Java實現一個簡單的RPC框架(三) 帶引數的本地呼叫

參考: 上面我們已經實現了通過我們指定的協議呼叫本地的其它類的函式來實現自己的功能,接下來我們要實現帶引數的RPC呼叫。 這裡我以add(a,b)為例子,為了實現這個功能,我們的請求方多了兩個引數a和b,那麼我們的RPC協議就要進行相應的修改:前面我們的請求方包含id和

java實現一個簡單Web伺服器

Web伺服器也稱為超文字傳輸協議伺服器,使用http與其客戶端進行通訊,基於java的web伺服器會使用兩個重要的類, java.net.Socket類和java.net.ServerSocket類,並基於傳送http訊息進行通訊。 這個簡單的Web伺服器會有以下三個類:

動手造輪子:實現一個簡單的 AOP 框架

# 動手造輪子:實現一個簡單的 AOP 框架 ## Intro 最近實現了一個 AOP 框架 -- FluentAspects,API 基本穩定了,寫篇文章分享一下這個 AOP 框架的設計。 ## 整體設計 ### 概覽 ![](https://img2020.cnblogs.com/blog/48

自己動手實現一個簡單的JSON解析器

pair bool 優點 輕量 結束 pan isdigit 復雜 false 1. 背景 JSON(JavaScript Object Notation) 是一種輕量級的數據交換格式。相對於另一種數據交換格式 XML,JSON 有著諸多優點。比如易讀性更好,占用空間更少等

JAVAWEB學習(12) - 實現一個簡單的MVC框架

實現一個簡單的MVC框架 1. 目標 SmartMVC核心是一個通用的控制器(DispatcherServlet)。利用SmartMVC,我們在開發一個web應用時,只需要新增相應的配置,通過該控制器就可以呼叫相應的模型或者檢視。也就是說,只需要寫模型和檢視,不再需要寫控制器了。

自己動手實現一個簡單的Mybatis(初級版本1.0)

手寫Mybatis-v1.0 原始碼連結(包括v1.0與v2.0): https://github.com/staticLin/customMyBatis.git 從上一個文章 ---Mybatis概述中瞭解到了Mybatis的主要架構與底層原理流程,結尾給出了一個巨集觀流程圖,可

使用akka實現一個簡單的RPC框架(一)

一、概述 目前大多數的分散式架構底層通訊都是通過RPC實現的,RPC框架非常多,比如前我們學過的Hadoop專案的RPC通訊框架,但是Hadoop在設計之初就是為了執行長達數小時的批量而設計的,在某些極端的情況下,任務提交的延遲很高,所有Hadoop的RPC顯得有些笨重。

實現一個簡單的MVC框架(SmartMVC)

建立一個maven工程(smartmvc-exec) 2.導包(dom4j) dom4j dom4j 1.6.1 3.新增一個jsp(/WEB-INF/hello.jsp) <%@ page pageEncoding=“utf-8” content

實現一個簡單Web伺服器(C語言)

Web伺服器 github地址 該專案的第二部分是在第一部分的基礎上繼續完善Web伺服器。 第二部分主要是完成兩個功能:記錄日誌和HTTP響應。 記錄日誌 該部分比較簡單,只要簡單地將一些伺服器的資訊新增到指定日誌檔案即可, 也不需要完成很複雜的功能,有了日誌功

go 語言實現一個簡單web 伺服器

學習Go語言的一些感受,不一定準確。假如發生戰爭,JAVA一般都是充當航母戰鬥群的角色。一旦出動,就是護衛艦、巡洋艦、航母艦載機、預警機、電子戰飛機、潛艇等等浩浩蕩蕩,殺將過去。(JVM,數十個JAR包,Tomcat中介軟體,SSH框架,各種配置檔案...天生就是重量級的,

深入理解Spring--動手實現一個簡單的SpringIOC容器

package com.wang.main; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.HashMap; import java.util.M

實現一個簡單web伺服器

實現一個簡單的Web伺服器myhttpd。伺服器程式啟動時要讀取配置檔案/etc/myhttpd.conf,其中需要指定伺服器監聽的埠號和服務目錄,例如: Port=80 Directory=/var/www 注意,1024以下的埠號需要超級使用者才能開啟服務。如果你的系統中已經安裝了某種Web

自己實現一個簡單的RPC框架

RPC的全稱是Remote Procedure Call,它是一種程序間的通訊方式。允許像呼叫本地服務一樣呼叫遠端服務。 對於RPC的總結: 簡單:RPC概念的語義十分簡單和清晰,這樣建立分散式計算更容易。 高效:過程呼叫看起來十分簡單而且十分高效。

自己動手一個簡單的MVC框架(第一版)

一、MVC概念回顧   路由(Route)、控制器(Controller)、行為(Action)、模型(Model)、檢視(View) 用一句簡單地話來描述以上關鍵點:   路由(Route)就相當於一個公司的前臺小姐,她負責帶你(請求)找到跟你面試的面試官(控制器Controller),面試官

自己動手一個簡單的MVC框架(第二版)

一、ASP.NET MVC核心機制回顧   在ASP.NET MVC中,最核心的當屬“路由系統”,而路由系統的核心則源於一個強大的System.Web.Routing.dll元件。   在這個System.Web.Routing.dll中,有一個最重要的類叫做UrlRoutingModule,它是一個

(14)樹莓派B+使用L298N驅動控制四驅車並實現一個簡單web控制端

在系列文章第12篇中提到了L298N,它是H橋雙路直流電機驅動,可以使雙路直流電機實現正轉或者反轉,並且通過ENDA和ENDB輸入PWM訊號,還可以實現加減速。本文用2塊L298N驅動板成功驅動了4個直流電機,實現了4輪同時向前、向後以及前向左轉、前向右轉甚至是後向左轉和後

自己動手實現一個簡單c編譯器

這學期的編譯課程設計需要做一個類c編譯器,準確的說是完善上學期做的大實驗。 上學期的實驗中,使用antlr完成的編譯器識別的語法很有限,基本上是個計算器的語法,於是這次決定弄語法一個更加完整。 語法支援: 宣告,賦值,函式,if-else,while,for。 首先是詞法分