30個(gè)類手寫Spring核心原理之環(huán)境準(zhǔn)備
1 IDEA集成Lombok插件
1.1 安裝插件
IntelliJ IDEA是一款非常優(yōu)秀的集成開(kāi)發(fā)工具,功能強(qiáng)大,而且插件眾多。Lombok是開(kāi)源的代碼生成庫(kù),是一款非常實(shí)用的小工具,我們?cè)诰庉媽?shí)體類時(shí)可以通過(guò)Lombok注解減少getter、setter等方法的編寫,在更改實(shí)體類時(shí)只需要修改屬性即可,減少了很多重復(fù)代碼的編寫工作。首先需要安裝IntelliJ IDEA中的Lombok插件,打開(kāi)IntelliJ IDEA后單擊菜單欄中的File→Settings(如下圖所示),或者使用快捷鍵Ctrl+Alt+S進(jìn)入設(shè)置界面。
單擊設(shè)置界面中的Plugins進(jìn)行插件的安裝,在右側(cè)單擊Browse repositories按鈕,如下圖所示。
然后在搜索界面中輸入lombok可以查詢到下方的Lombok Plugin,單擊Lombok Plugin可在右側(cè)看到Install按鈕,單擊該按鈕便可開(kāi)始安裝,如下圖所示。
我們?cè)谌缦掳惭b界面可以看到Lombok支持的所有注解。
在安裝過(guò)程中有Downloading Plugins的提示,安裝過(guò)程中進(jìn)度條會(huì)變化。需要提醒的是,在安裝過(guò)程中一定要保證網(wǎng)絡(luò)連接可用且良好,否則可能會(huì)安裝失敗。安裝成功后可以看到下圖右側(cè)的Restart IntelliJ IDEA按鈕,此時(shí)可先不操作,因?yàn)檫€有后續(xù)的配置工作。
回到Plugins,此時(shí)在下圖右側(cè)可以搜索到Lombok(而安裝前搜索不到)。
1.2 配置注解處理器
在如下設(shè)置界面單擊Build, Execution, Deployment→Compiler→Annotation Processors,然后在右側(cè)勾選Enable annotation processing復(fù)選項(xiàng)即可。
1.3 使用插件
使用前需要說(shuō)明的是,安裝的插件只是一個(gè)調(diào)用,就像我們使用maven插件一樣,本機(jī)需要安裝maven才行。我們?cè)谑褂肔ombok前也需要在pom.xml文件中添加Lombok的依賴。
- #托管的類掃描包路徑#
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.16.10</version>
- </dependency>
接下來(lái)編輯一個(gè)Config測(cè)試類,添加兩個(gè)屬性,最后在類上添加@Data屬性,這個(gè)注解可以幫我們?cè)?class文件中生成類中所有屬性的get/set、equals、canEqual、hashCode、toString方法等,如下圖所示。
我們還可以通過(guò)下面的方式查看Lombok生成的方法。在菜單欄中單擊View→Tool Windows→Structure,便可以看到類中所有的方法,這些都是Lombok自動(dòng)生成的,如下面兩圖所示。
2 從Servlet到ApplicationContext
在“用300行代碼手寫提煉Spring核心原理”一章中,我們已經(jīng)了解Spring MVC的入口是DispatcherSerlvet,并實(shí)現(xiàn)了DispatcherServlet的init()方法,在init()方法中完成了IoC容器的初始化。而在使用Spring的過(guò)程中,見(jiàn)得最多的是ApplicationContext,似乎Spring托管的所有實(shí)例Bean都可以通過(guò)調(diào)用getBean()方法來(lái)獲得。那么ApplicationContext又是從何而來(lái)的呢?從Spring源碼中可以看到,DispatcherServlet的類圖如下圖所示。
DispatcherServlet繼承了FrameworkServlet,F(xiàn)rameworkServlet繼承了HttpServletBean,HttpServletBean繼承了HttpServlet。在HttpServletBean的init()方法中調(diào)用了FrameworkServlet的initServletBean()方法,在initServletBean()方法中初始化WebApplicationContext實(shí)例。在initServletBean()方法中調(diào)用了DispatcherServlet重寫的onRefresh()方法。在DispatcherServlet的onRefresh()方法中又調(diào)用了initStrategies()方法,初始化Spring MVC的九大組件。其實(shí),通過(guò)上面復(fù)雜的調(diào)用關(guān)系可以得出一個(gè)結(jié)論:在Servlet的init()方法中初始化了IoC容器和Spring MVC所依賴的九大組件。在手寫之前先將框架類關(guān)系畫出來(lái),如下圖所示,順便也回顧一下我們之前講過(guò)的IoC容器結(jié)構(gòu)。
3 準(zhǔn)備基礎(chǔ)配置
在開(kāi)始手寫之前我們先做一個(gè)約定,所有的手寫類都以GP開(kāi)頭,以區(qū)別于Spring框架中的原生類,方便對(duì)比理解。如DispatcherServlet在這個(gè)Mini版本中會(huì)命名為GPDispatcherServlet,所有的方法名盡量和原生Spring保持一致,可能有些參數(shù)列表會(huì)做一些微調(diào),主要目的是理解設(shè)計(jì)思路。
3.1 application.properties配置
還是先從application.properties文件開(kāi)始,用application.properties來(lái)代替application.xml,具體配置如下:
- #托管的類掃描包路徑#
- scanPackage=com.gupaoedu.vip.spring.demo
3.2 pom.xml配置
接下來(lái)看pom.xml的配置,主要關(guān)注jar包依賴:
- <properties>
- <!-- dependency versions -->
- <servlet.api.version>2.4</servlet.api.version>
- </properties>
- <dependencies>
- <!-- requied start -->
- <dependency>
- <groupId>javax.servlet</groupId>
- <artifactId>servlet-api</artifactId>
- <version>${servlet.api.version}</version>
- <scope>provided</scope>
- </dependency>
- <!-- requied end -->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- <version>1.16.10</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>1.7.25</version>
- </dependency>
- <dependency>
- <groupId>ch.qos.logback</groupId>
- <artifactId>logback-classic</artifactId>
- <version>1.2.3</version>
- </dependency>
- </dependencies>
3.3 web.xml配置
web.xml配置如下:
- <?xml version="1.0" encoding="UTF-8"?>
- <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:javaee="http://java.sun.com/xml/ns/javaee"
- xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
- xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
- version="2.4">
- <display-name>Gupao Spring Application</display-name>
- <servlet>
- <servlet-name>gupaomvc</servlet-name>
- <servlet-class>com.gupaoedu.vip.spring.formework.webmvc.servlet.GPDispatcherServlet </servlet-class>
- <init-param>
- <param-name>contextConfigLocation</param-name>
- <param-value>classpath:application.properties</param-value>
- </init-param>
- <load-on-startup>1</load-on-startup>
- </servlet>
- <servlet-mapping>
- <servlet-name>gupaomvc</servlet-name>
- <url-pattern>/*</url-pattern>
- </servlet-mapping>
- </web-app>
3.4 GPDispatcherServlet
GPDispatcherServlet代碼如下:
- package com.gupaoedu.vip.spring.formework.webmvc.servlet;
- 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.IOException;
- //Servlet只是作為一個(gè)MVC的啟動(dòng)入口
- public class GPDispatcherServlet extends HttpServlet {
- @Override
- public void init(ServletConfig config) throws ServletException {
- }
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- this.doPost(req,resp);
- }
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- }
- }
用30個(gè)類手寫一個(gè)Spring的準(zhǔn)備階段就到此為止,大家一定要記得自己動(dòng)手操作。光看不練假把式。