0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

如何基于 Servlet 進(jìn)行開(kāi)發(fā)

Android編程精選 ? 來(lái)源:Android編程精選 ? 2023-05-24 09:18 ? 次閱讀

隨著 Spring 的崛起以及其功能的完善,現(xiàn)在可能絕大部分項(xiàng)目的開(kāi)發(fā)都是使用 Spring(全家桶) 來(lái)進(jìn)行開(kāi)發(fā),Spring也確實(shí)和其名字一樣,是開(kāi)發(fā)者的春天,Spring 解放了程序員的雙手,而等到 SpringBoot出來(lái)之后配置文件大大減少,更是進(jìn)一步解放了程序員的雙手,但是也正是因?yàn)镾pring家族產(chǎn)品的強(qiáng)大,使得我們習(xí)慣了面向 Spring 開(kāi)發(fā),那么假如有一天沒(méi)有了 Spring,是不是感覺(jué)心里一空,可能一下子連最基本的接口都不會(huì)寫(xiě)了,尤其是沒(méi)有接觸過(guò)Servlet編程的朋友。因?yàn)榧尤霙](méi)有了 Spring 等框架,那么我們就需要利用最原生的 Servlet 來(lái)自己實(shí)現(xiàn)接口路徑的映射,對(duì)象也需要自己進(jìn)行管理。
# Spring 能幫我們做什么
Spring 是為解決企業(yè)級(jí)應(yīng)用開(kāi)發(fā)的復(fù)雜性而設(shè)計(jì)的一款框架,Spring 的設(shè)計(jì)理念就是:簡(jiǎn)化開(kāi)發(fā)。

在 Spring 框架中,一切對(duì)象都是 bean,所以其通過(guò)面向 bean 編程(BOP),結(jié)合其核心思想依賴(lài)注入(DI)和面向切面((AOP)編程,Spring 實(shí)現(xiàn)了其偉大的簡(jiǎn)化開(kāi)發(fā)的設(shè)計(jì)理念。
# 控制反轉(zhuǎn)(IOC)
IOC 全稱(chēng)為:Inversion of Control??刂品崔D(zhuǎn)的基本概念是:不用創(chuàng)建對(duì)象,但是需要描述創(chuàng)建對(duì)象的方式。
簡(jiǎn)單的說(shuō)我們本來(lái)在代碼中創(chuàng)建一個(gè)對(duì)象是通過(guò) new 關(guān)鍵字,而使用了 Spring 之后,我們不在需要自己去 new 一個(gè)對(duì)象了,而是直接通過(guò)容器里面去取出來(lái),再將其自動(dòng)注入到我們需要的對(duì)象之中,即:依賴(lài)注入。
也就說(shuō)創(chuàng)建對(duì)象的控制權(quán)不在我們程序員手上了,全部交由 Spring 進(jìn)行管理,程序要只需要注入就可以了,所以才稱(chēng)之為控制反轉(zhuǎn)
# 依賴(lài)注入(DI) 依賴(lài)注入(Dependency Injection,DI)就是 Spring 為了實(shí)現(xiàn)控制反轉(zhuǎn)的一種實(shí)現(xiàn)方式,所有有時(shí)候我們也將控制反轉(zhuǎn)直接稱(chēng)之為依賴(lài)注入。
# 面向切面編程(AOP) AOP 全稱(chēng)為:Aspect Oriented Programming。AOP是一種編程思想,其核心構(gòu)造是方面(切面),即將那些影響多個(gè)類(lèi)的公共行為封裝到可重用的模塊中,而使原本的模塊內(nèi)只需關(guān)注自身的個(gè)性化行為。
AOP 編程的常用場(chǎng)景有:Authentication(權(quán)限認(rèn)證)、Auto Caching(自動(dòng)緩存處理)、Error Handling(統(tǒng)一錯(cuò)誤處理)、Debugging(調(diào)試信息輸出)、Logging(日志記錄)、Transactions(事務(wù)處理)等。
# 利用 Spring 來(lái)完成 Hello World 最原生的 Spring 需要較多的配置文件,而 SpringBoot 省略了許多配置,相比較于原始的 Spring 又簡(jiǎn)化了不少,在這里我們就以 SpringBoot 為例來(lái)完成一個(gè)簡(jiǎn)單的接口開(kāi)發(fā)。
1、新建一個(gè) maven 項(xiàng)目,pom 文件中引入依賴(lài)(省略了少部分屬性):


    org.springframework.boot
    spring-boot-starter-parent
    2.4.0
    


    
        org.springframework.boot
        spring-boot-starter



    
        org.springframework.boot
        spring-boot-starter-web
    
2、新建一個(gè) HelloController 類(lèi):
packagecom.lonely.wolf.note.springboot.demo;


import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping("/hello")
public class HelloController {
    @GetMapping("/demo")
    public String helloWorld(String name){
        return "Hello:" + name;
    }
}
3、最后新建一個(gè) SpringBoot 啟動(dòng)類(lèi):
package com.lonely.wolf.note.springboot;


import org.springframework.boot.SpringApplication;
importorg.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication(scanBasePackages = "com.lonely.wolf.note.springboot")
class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class, args);
    }
}
4、現(xiàn)在就可以輸入測(cè)試路徑:http://localhost:8080/hello/demo?name=雙子孤狼 進(jìn)行測(cè)試,正常輸出:Hello:雙子孤狼。 我們可以看到,利用 SpringBoot 來(lái)完成一個(gè)簡(jiǎn)單的應(yīng)用開(kāi)發(fā)非常簡(jiǎn)單,可以不需要任何配置完成一個(gè)簡(jiǎn)單的應(yīng)用,這是因?yàn)?SpringBoot 內(nèi)部已經(jīng)做好了約定(約定優(yōu)于配置思想),包括容器 Tomcat 都被默認(rèn)集成,所以我們不需要任何配置文件就可以完成一個(gè)簡(jiǎn)單的 demo 應(yīng)用。 # 假如沒(méi)有了 Spring 通過(guò)上面的例子我們可以發(fā)現(xiàn),利用 Spring 來(lái)完成一個(gè) Hello World 非常簡(jiǎn)單,但是假如沒(méi)有了 Spring,我們又該如何完成這樣的一個(gè) Hello World 接口呢? # 基于 Servlet 開(kāi)發(fā) 在還沒(méi)有框架之前,編程式基于原始的 Servlet 進(jìn)行開(kāi)發(fā),下面我們就基于原生的 Servlet 來(lái)完成一個(gè)簡(jiǎn)單的接口調(diào)用。 1、pom 文件引入依賴(lài),需要注意的是,package 屬性要設(shè)置成 war 包,為了節(jié)省篇幅,這里沒(méi)有列出 pom 完整的信息:
war

        
            javax.servlet
            servlet-api
            2.4



        
            org.apache.commons
            commons-lang3
            3.7



        
            com.alibaba
            fastjson
            1.2.72
        
    
2、在 src/main 下面新建文件夾 webapp/WEB-INF,然后在 WEB-INF 下面新建一個(gè) web.xml 文件:


 Lonely Wolf Web Application
 
  helloServlet
  com.lonely.wolf.mini.spring.servlet.HelloServlet
 
 
  helloServlet
  /hello/*
 
這里面定義了 selvlet 和 servlet-mapping 兩個(gè)標(biāo)簽,這兩個(gè)標(biāo)簽必須一一對(duì)應(yīng),上面的標(biāo)簽定義了 servlet 的位置,而下面的 servlet-mapping 文件定義了路徑的映射,這兩個(gè)標(biāo)簽通過(guò) servlet-name 標(biāo)簽對(duì)應(yīng)。 3、新建一個(gè) HelloServlet 類(lèi)繼承 HttpServlet:
packagecom.lonely.wolf.mini.spring.servlet;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
importjava.io.IOException;


/**
 * 原始Servlet接口編寫(xiě),一般需要實(shí)現(xiàn)GET和POST方法,其他方法可以視具體情況選擇性繼承
 */
public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
}


    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("Hello:" + request.getParameter("name"));
    }
}
4、執(zhí)行 maven 打包命令,確認(rèn)成功打包成 war 包:

13f04d52-f991-11ed-90ce-dac502259ad0.png

5、RUN-->Edit Configurations,然后點(diǎn)擊左上角的 + 號(hào),新建一個(gè) Tomcat Server,如果是第一次配置,默認(rèn)沒(méi)有 Tomcat Server 選項(xiàng),需要點(diǎn)擊底部的 xx more items...:

140856fe-f991-11ed-90ce-dac502259ad0.png

6、點(diǎn)擊右邊的 Deployment,然后按照下圖依次點(diǎn)擊,最后在彈框內(nèi)找到上面打包好的 war 包文件:

14411d36-f991-11ed-90ce-dac502259ad0.png

7、選中之后,需要注意的是,下面 Application Context 默認(rèn)會(huì)帶上 war 包名,為了方便,我們需要把它刪掉,即不用上下文路徑,只保留一個(gè)根路徑 / (當(dāng)然上下文也可以保留,但是每次請(qǐng)求都要帶上這一部分), 再選擇 Apply,點(diǎn)擊 OK,即可完成部署:

144ff81a-f991-11ed-90ce-dac502259ad0.png

8、最后我們?cè)跒g覽器輸入請(qǐng)求路徑http://localhost:8080/hello?name=雙子孤狼,即可得到返回:Hello:雙子孤狼。 上面我們就完成了一個(gè)簡(jiǎn)單的 基于Servlet 的接口開(kāi)發(fā),可以看到,配置非常麻煩,每增加一個(gè) Servlet 都需要增加對(duì)應(yīng)的配置,所以才會(huì)有許多框架的出現(xiàn)來(lái)幫我們簡(jiǎn)化開(kāi)發(fā),比如原來(lái)很流行的 Struts2 框架,當(dāng)然現(xiàn)在除了一些比較老的項(xiàng)目,一般我們都很少使用,而更多的是選擇 Spring 框架來(lái)進(jìn)行開(kāi)發(fā)。 # 模仿 Spring Spring 的源碼體系非常龐大,大部分人對(duì)其源碼都敬而遠(yuǎn)之。確實(shí),Spring 畢竟經(jīng)過(guò)了這么多年的迭代,功能豐富,項(xiàng)目龐大,不是一下子就能看懂的。雖然 Spring 難以理解,但是其最核心的思想仍然是我們上面介紹的幾點(diǎn),接下來(lái)就基于 Spring 最核心的部分來(lái)模擬,自己動(dòng)手實(shí)現(xiàn)一個(gè)超級(jí)迷你版本的 Spring(此版本并不包含 AOP 功能)。 1、pom 依賴(lài)和上面保持不變,然后 web.xml 作如下改變,這里會(huì)攔截所有的接口 /*,然后多配置了一個(gè)參數(shù),這個(gè)參數(shù)其實(shí)也是為了更形象的模擬 Spring:


    myDispatcherServlet
    com.lonely.wolf.mini.spring.v1.MyDispatcherServlet
    
        defaultConfig
        application.properties
    




    myDispatcherServlet
    /*
2、在 respurces 下面新建一個(gè)配置文件 application.properties,用來(lái)定義掃描的基本路徑:
basePackages=com.lonely.wolf.mini.spring
3、創(chuàng)建一些相關(guān)的注解類(lèi):
package com.lonely.wolf.mini.spring.annotation;


import java.lang.annotation.*;


@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WolfAutowired {
    String value() default "";
}
package com.lonely.wolf.mini.spring.annotation;


import java.lang.annotation.*;


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WolfController {
    String value() default "";
}
package com.lonely.wolf.mini.spring.annotation;


import java.lang.annotation.*;


@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WolfGetMapping {
    String value() default "";
}
package com.lonely.wolf.mini.spring.annotation;


importjava.lang.annotation.*;


@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WolfRequestParam {
    String value() default "";
}
packagecom.lonely.wolf.mini.spring.annotation;


importjava.lang.annotation.*;


@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface WolfService {
    String value() default "";
}
4、這個(gè)時(shí)候最核心的邏輯就是 MyDispatcherServlet 類(lèi)了:
package com.lonely.wolf.mini.spring.v1;


import com.lonely.wolf.mini.spring.annotation.*;
import com.lonely.wolf.mini.spring.v1.config.MyConfig;
importorg.apache.commons.lang3.StringUtils;


import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.URL;
importjava.util.*;


public class MyDispatcherServlet extends HttpServlet {
    private MyConfig myConfig = new MyConfig();
    private List classNameList = new ArrayList();


    private Map iocContainerMap = new HashMap<>();
privateMaphandlerMappingMap=newHashMap<>();


    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doPost(request,response);
}


    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            this.doDispatch(request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
}


    private void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception{
        String requestUrl = this.formatUrl(request.getRequestURI());
        HandlerMapping handlerMapping = handlerMappingMap.get(requestUrl);
        if (null == handlerMapping){
            response.getWriter().write("404 Not Found");
            return;
}


        //獲取方法中的參數(shù)類(lèi)型
        Class[] paramTypeArr = handlerMapping.getMethod().getParameterTypes();
Object[]paramArr=newObject[paramTypeArr.length];


        for (int i=0;i clazz = paramTypeArr[i];
            //參數(shù)只考慮三種類(lèi)型,其他不考慮
            if (clazz == HttpServletRequest.class){
                paramArr[i] = request;
            }else if (clazz == HttpServletResponse.class){
                paramArr[i] = response;
            } else if (clazz == String.class){
                Map methodParam = handlerMapping.getMethodParams();
                paramArr[i] = request.getParameter(methodParam.get(i));
            }else{
                System.out.println("暫不支持的參數(shù)類(lèi)型");
            }
        }
        //反射調(diào)用controller方法
        handlerMapping.getMethod().invoke(handlerMapping.getTarget(), paramArr);
}


    private String formatUrl(String requestUrl) {
        requestUrl = requestUrl.replaceAll("/+","/");
        if (requestUrl.lastIndexOf("/") == requestUrl.length() -1){
            requestUrl = requestUrl.substring(0,requestUrl.length() -1);
        }
        return requestUrl;
}


    @Override
    public void init(ServletConfig config) throws ServletException {
        //1.加載配置文件
        try {
            doLoadConfig(config.getInitParameter("defaultConfig"));
        } catch (Exception e) {
            System.out.println("加載配置文件失敗");
            return;
}


        //2.根據(jù)獲取到的掃描路徑進(jìn)行掃描
doScanPacakge(myConfig.getBasePackages());


        //3.將掃描到的類(lèi)進(jìn)行初始化,并存放到IOC容器
doInitializedClass();


        //4.依賴(lài)注入
doDependencyInjection()


        System.out.println("DispatchServlet Init End..." );
}


    private void doDependencyInjection() {
        if (iocContainerMap.size() == 0){
            return;
        }
        //循環(huán)IOC容器中的類(lèi)
Iterator>iterator=iocContainerMap.entrySet().iterator();


        while (iterator.hasNext()){
            Map.Entry entry = iterator.next();
            Class clazz = entry.getValue().getClass();
Field[]fields=clazz.getDeclaredFields();


            //屬性注入
            for (Field field : fields){
                //如果屬性有WolfAutowired注解則注入值(暫時(shí)不考慮其他注解)
                if (field.isAnnotationPresent(WolfAutowired.class)){
                    String value = toLowerFirstLetterCase(field.getType().getSimpleName());//默認(rèn)bean的value為類(lèi)名首字母小寫(xiě)
                    if (field.getType().isAnnotationPresent(WolfService.class)){
                        WolfService wolfService = field.getType().getAnnotation(WolfService.class);
                        value = wolfService.value();
                    }
                    field.setAccessible(true);
                    try {
                        Object target = iocContainerMap.get(beanName);
                        if (null == target){
                            System.out.println(clazz.getName() + "required bean:" + beanName + ",but we not found it");
                        }
                        field.set(entry.getValue(),iocContainerMap.get(beanName));//初始化對(duì)象,后面注入
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
}


            //初始化HanderMapping
            String requestUrl = "";
            //獲取Controller類(lèi)上的請(qǐng)求路徑
            if (clazz.isAnnotationPresent(WolfController.class)){
                requestUrl = clazz.getAnnotation(WolfController.class).value();
}


            //循環(huán)類(lèi)中的方法,獲取方法上的路徑
            Method[] methods = clazz.getMethods();
            for (Method method : methods){
                //假設(shè)只有WolfGetMapping這一種注解
                if(!method.isAnnotationPresent(WolfGetMapping.class)){
                    continue;
                }
                WolfGetMapping wolfGetMapping = method.getDeclaredAnnotation(WolfGetMapping.class);
requestUrl=requestUrl+"/"+wolfGetMapping.value();//拼成完成的請(qǐng)求路徑


                //不考慮正則匹配路徑/xx/* 的情況,只考慮完全匹配的情況
                if (handlerMappingMap.containsKey(requestUrl)){
                    System.out.println("重復(fù)路徑");
                    continue;
                }


Annotation[][]annotationArr=method.getParameterAnnotations();//獲取方法中參數(shù)的注解


                Map methodParam = new HashMap<>();//存儲(chǔ)參數(shù)的順序和參數(shù)名
                retryParam:
                for (int i=0;i {
            try {
                Field field = myConfig.getClass().getDeclaredField((String)k);
                field.setAccessible(true);
                field.set(myConfig,v);
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("初始化配置類(lèi)失敗");
                return;
            }
        });
    }
}
5、這個(gè) Servlet 相比較于上面的 HelloServlet 多了一個(gè) init 方法,這個(gè)方法中主要做了以下幾件事情:

初始化配置文件,拿到配置文件中配置的參數(shù)信息(對(duì)應(yīng)方法:doLoadConfig)。

拿到第 1 步加載出來(lái)的配置文件,獲取到需要掃描的包路徑,然后將包路徑進(jìn)行轉(zhuǎn)換成實(shí)際的磁盤(pán)路徑,并開(kāi)始遍歷磁盤(pán)路徑下的所有 class 文件,最終經(jīng)過(guò)轉(zhuǎn)換之后得到掃描路徑下的所有類(lèi)的全限定類(lèi)型,存儲(chǔ)到全局變量 classNameList 中(對(duì)應(yīng)方法:doScanPacakge)。

根據(jù)第 2 步中得到的全局變量 classNameList 中的類(lèi)通過(guò)反射進(jìn)行初始化(需要注意的是只會(huì)初始化加了指定注解的類(lèi))并將得到的對(duì)應(yīng)關(guān)系存儲(chǔ)到全局變量 iocContainerMap 中(即傳說(shuō)中的 IOC 容器),其中 key 值為注解中的 value 屬性,如 value 屬性為空,則默認(rèn)取首字母小寫(xiě)的類(lèi)名作為 key 值進(jìn)行存儲(chǔ)(對(duì)應(yīng)方法:doInitializedClass)。

這一步比較關(guān)鍵,需要對(duì) IOC 容器中的所有類(lèi)的屬性進(jìn)行賦值并且需要對(duì) Controller 中的請(qǐng)求路徑進(jìn)行映射存儲(chǔ),為了確保最后能順利調(diào)用 Controller 中的方法,還需要將方法的參數(shù)進(jìn)行存儲(chǔ) 。對(duì)屬性進(jìn)行映射時(shí)只會(huì)對(duì)加了注解的屬性進(jìn)行映射,映射時(shí)會(huì)從 IOC 容器中取出第 3 步中已經(jīng)初始化的實(shí)例對(duì)象進(jìn)行賦值,最后將請(qǐng)求路徑和 Controller 中方法的映射關(guān)系存入變量 handlerMappingMap,key 值為請(qǐng)求路徑,value 為方法的相關(guān)信息 (對(duì)應(yīng)方法:doDependencyInjection)。

6、存儲(chǔ)請(qǐng)求路徑和方法的映射關(guān)系時(shí),需要用到 HandlerMapping 類(lèi)來(lái)進(jìn)行存儲(chǔ):

packagecom.lonely.wolf.mini.spring.v1;


import java.lang.reflect.Method;
importjava.util.Map;


//省略了getter/setter方法
public class HandlerMapping {
    private String requestUrl;
    private Object target;//保存方法對(duì)應(yīng)的實(shí)例
    private Method method;//保存映射的方法
    private Map methodParams;//記錄方法參數(shù)
}
7、初始化完成之后,因?yàn)閿r截了 /* ,所以調(diào)用任意接口都會(huì)進(jìn)入 MyDispatcherServlet ,而且最終都會(huì)執(zhí)行方法 doDispatch,執(zhí)行這個(gè)方法時(shí)會(huì)拿到請(qǐng)求的路徑,然后和全局變量 handlerMappingMap 進(jìn)行匹配,匹配不上則返回 404,匹配的上則取出必要的參數(shù)進(jìn)行賦值,最后通過(guò)反射調(diào)用到 Controller 中的相關(guān)方法。 8、新建一個(gè) HelloController 和 HelloService 來(lái)進(jìn)行測(cè)試:
packagecom.lonely.wolf.mini.spring.controller;


import com.lonely.wolf.mini.spring.annotation.WolfAutowired;
import com.lonely.wolf.mini.spring.annotation.WolfController;
import com.lonely.wolf.mini.spring.annotation.WolfGetMapping;
import com.lonely.wolf.mini.spring.annotation.WolfRequestParam;
importcom.lonely.wolf.mini.spring.service.HelloService;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


@WolfController
public class HelloController {
    @WolfAutowired
privateHelloServicehelloService;


    @WolfGetMapping("/hello")
    public void query(HttpServletRequest request,HttpServletResponse response, @WolfRequestParam("name") String name) throws IOException {
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().write("Hello:" + name);
    }
}
packagecom.lonely.wolf.mini.spring.service;


importcom.lonely.wolf.mini.spring.annotation.WolfService;


@WolfService(value = "hello_service")//為了演示能否正常取value屬性
public class HelloService {
}
9、輸入測(cè)試路徑:http://localhost:8080////hello?name=雙子孤狼, 進(jìn)行測(cè)試發(fā)現(xiàn)可以正常輸出:Hello:雙子孤狼。 上面這個(gè)例子只是一個(gè)簡(jiǎn)單的演示,通過(guò)這個(gè)例子只是希望在沒(méi)有任何框架的情況下,我們也能知道如何完成一個(gè)簡(jiǎn)單的應(yīng)用開(kāi)發(fā)。例子中很多細(xì)節(jié)都沒(méi)有進(jìn)行處理,僅僅只是為了體驗(yàn)一下 Spring 的核心思想,并了解 Spring 到底幫助我們做了什么,實(shí)際上 Spring 能幫我們做的事情遠(yuǎn)比這個(gè)例子中多得多,Spring 體系龐大,設(shè)計(jì)優(yōu)雅,經(jīng)過(guò)了多年的迭代優(yōu)化,是一款非常值得研究的框架。 # 總結(jié) 本文從介紹 Spring 核心功能開(kāi)始入手,從如何利用 Spring 完成一個(gè)應(yīng)用開(kāi)發(fā),講述到假如沒(méi)有 Spring 我們?cè)撊绾位?Servlet 進(jìn)行開(kāi)發(fā),最后再通過(guò)一個(gè)簡(jiǎn)單的例子體驗(yàn)了 Spring 的核心思想。
審核編輯:彭靜
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 編程
    +關(guān)注

    關(guān)注

    88

    文章

    3619

    瀏覽量

    93781
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14353
  • Servlet
    +關(guān)注

    關(guān)注

    0

    文章

    18

    瀏覽量

    7899

原文標(biāo)題:不用 Spring 居然連最基本的接口都不會(huì)寫(xiě)了!

文章出處:【微信號(hào):AndroidPush,微信公眾號(hào):Android編程精選】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    servlet2.3規(guī)范中文版

    servlet2.3規(guī)范中文版第一章:servlet2.3規(guī)范用到了一下的一些規(guī)范:J2EE、JSP1.1、JNDI在14章中講述了規(guī)范中的所有的classes類(lèi)或接口(改文中不講述)。對(duì)開(kāi)發(fā)者而言
    發(fā)表于 07-07 15:27

    Servlet入門(mén)----創(chuàng)建第一個(gè)自己的Servlet小程序

    Servlet入門(mén)----創(chuàng)建第一個(gè)自己的Servlet小程序使用開(kāi)發(fā)工具創(chuàng)建第一步:打開(kāi)Myeclipse或者Eclipse,新建一個(gè)Web project,然后新建一個(gè)類(lèi)Demo01.java
    發(fā)表于 01-31 13:48

    如何修改Servlet容器的相關(guān)配置呢

    配置嵌入式Servlet容器##Spring Boot里面內(nèi)置了嵌入式的Servlet容器(tomcat)點(diǎn)擊pom.xml->右鍵->Diagrams->show
    發(fā)表于 10-27 09:10

    如何定制和修改Servlet容器的相關(guān)配置

    1.背景SpringBoot默認(rèn)使用Tomcat作為嵌入式的Servlet容器。2.如何定制和修改Servlet容器的相關(guān)配置1.修改與server相關(guān)的配置server.port
    發(fā)表于 12-16 06:08

    內(nèi)嵌的Servlet配置如何修改

    SpringBoot默認(rèn)采用嵌入式的Servlet容器(Tomcat)。那么內(nèi)嵌的Servlet配置如何修改?可以使用配置文件或者yml文件來(lái)修改server:port
    發(fā)表于 12-16 06:05

    如何配置嵌入式的Servlet容器?

    以前的web應(yīng)用開(kāi)發(fā)我們采取的方式是項(xiàng)目完成后打包成war包,然后配置tomcat啟動(dòng)運(yùn)行項(xiàng)目,而Spring Boot默認(rèn)使用的是嵌入式的tomcat,那我們需要如何配置嵌入式的Servlet容器
    發(fā)表于 12-20 07:18

    SpringBoot配置嵌入式Servlet

    SpringBoot配置嵌入式Servlet容器定制和修改Servlet容器相關(guān)配置全局配置文件編寫(xiě)WebServerFactoryCustomizer注冊(cè)Servlet三大組件注冊(cè)Servl
    發(fā)表于 12-20 06:19

    如何對(duì)嵌入式Servlet容器進(jìn)行配置呢

    一、配置嵌入式Servlet容器SpringBoot默認(rèn)使用Tomcat作為嵌入式的Servlet容器;1、定制和修改Servlet容器的相關(guān)配置(1)、修改和server有關(guān)的配置
    發(fā)表于 12-21 06:09

    嵌入式Servlet容器啟動(dòng)原理

    學(xué)習(xí)專(zhuān)欄,里面有對(duì)SpringBoot的源碼進(jìn)行學(xué)習(xí)的一些博客,內(nèi)容比較簡(jiǎn)單,比較適合入門(mén)學(xué)習(xí)對(duì)于SpringBoot項(xiàng)目是不需要配置Tomcat、jetty等等Servlet容器,直接啟動(dòng)appl...
    發(fā)表于 12-22 07:23

    如何配置嵌入式Servlet容器

    springboot默認(rèn)使用的是嵌入式的servlet容器(tomcat):定制和修改servlet容器的相關(guān)配置1)修改和server有關(guān)的配置(ServerProperties類(lèi)
    發(fā)表于 12-24 06:56

    JSP與Servlet技術(shù)

    實(shí)驗(yàn)14  JSP與Servlet技術(shù)*一、實(shí)驗(yàn)?zāi)康?1. 理解JSP元素的概念2. 理解JSP 頁(yè)面中生成靜態(tài)內(nèi)容和動(dòng)態(tài)內(nèi)容的機(jī)制3. 理解JSP 頁(yè)面的服務(wù)
    發(fā)表于 09-23 19:06 ?1582次閱讀

    JAVA教程之客戶登錄Servlet小程序

    JAVA教程之客戶登錄Servlet小程序,很好的JAVA的資料,快來(lái)學(xué)習(xí)吧。
    發(fā)表于 04-13 09:58 ?3次下載

    深入研究Servlet線程安全性問(wèn)題

    Servlet是Java Servlet的簡(jiǎn)稱(chēng),稱(chēng)為小服務(wù)程序或服務(wù)連接器,用Java編寫(xiě)的服務(wù)器端程序,主要功能在于交互式地瀏覽和修改數(shù)據(jù),生成動(dòng)態(tài)Web內(nèi)容。狹義的Servlet是指Java語(yǔ)言實(shí)現(xiàn)的一個(gè)接口
    發(fā)表于 12-01 14:03 ?1907次閱讀
    深入研究<b class='flag-5'>Servlet</b>線程安全性問(wèn)題

    如何使用Java ME和Servlet進(jìn)行移動(dòng)成績(jī)查詢(xún)系統(tǒng)的設(shè)計(jì)實(shí)現(xiàn)

    簡(jiǎn)要地分析系統(tǒng)架構(gòu),并利用J2ME/Servlet技術(shù)設(shè)計(jì)了一個(gè)移動(dòng)成績(jī)查詢(xún)系統(tǒng).列舉服務(wù)器端和客戶端的主要代碼。
    發(fā)表于 01-11 16:20 ?21次下載
    如何使用Java ME和<b class='flag-5'>Servlet</b><b class='flag-5'>進(jìn)行</b>移動(dòng)成績(jī)查詢(xún)系統(tǒng)的設(shè)計(jì)實(shí)現(xiàn)

    嵌入式Servlet容器

    配置嵌入式Servlet容器##Spring Boot里面內(nèi)置了嵌入式的Servlet容器(tomcat)點(diǎn)擊pom.xml->右鍵->Diagrams->show
    發(fā)表于 10-20 17:51 ?3次下載
    嵌入式<b class='flag-5'>Servlet</b>容器