自己实现spring核心功能 一
?
聊聊spring
? ? ? ?spring對于java開發者來說,是最熟悉不過的框架了,我們日常開發中每天都在使用它。它有著各種各樣的好處,簡單易用,得心應手... ...
我們一說到spring就會講到ioc 、aop、依賴注入,注解等專業名詞,不少剛接觸java的人,都是一頭霧水,很難直觀的去理解這些是個什么玩意,但使用的多了?就愛上了它給我們帶來的便利。
?
探索spring
? ? ?當我們熟練的使用它之后就會好奇,ioc怎么實現的呢?為什么我只要在類的變量中加入@AutoWrited?就能使用這個變量?帶著疑惑我們就會開始翻源碼,找答案。經過一番努力,最終我們定位到了spring-context.jar包,找到了
AbstractApplicationContext對象的refresh方法,這里面的實現和步驟,就是整個spring功能的核心,里面的實現另我們嘆為觀止,但也相當之復雜,用到了很大設計模式,難以窺見全貌,很多地方的設計我們不知道為啥需要這么實現。但我們還是知道了ioc容器實際上是用的Hashmap,依賴注入使用的是反射,aop實際上是動態代理完成的。還有很大一部分代碼看的有點暈,就是加強健壯性保證生命周期和各種特性的。不管怎么說,那都是別人的東西,我們只會用,源碼我們看了很多,但很少自己來實現出來。
spring實現分析
? 不管怎么說,別人的實現是別人的,自己寫出來的東西是屬于我們自己的。既然下決心要自己也能實現了,那我們就需要分析分析了。
? ? ? spring怎么做到代碼侵入量少且各層級分明的呢?
? ? ? ? ?spring采用約定大于配置,按照固定模式,層級分為Controller 、Service、Component、Bean、Configuration來標識類型
? ? ? spring是怎么管理依賴關系的?
? ? ? ? ? 是通過注解或xml
? ? ? spring是怎么發現哪些類需要管理的?
? ? ? ? ? 是注解標記+包路徑掃描
? ? ? spring是如何實現依賴注入的?
? ? ? ? ?通過AutoWrited注解標記加反射實例化對象
? ? ? spring是如何管理Bean的?
? ? ? ? ?使用HashMap容器、Set容器實現單例Bean
? ? ? spring怎么實現aop切面的呢?
? ? ? ? ?使用動態代理的方式,并提供了cglib和jdk默認實現兩種方式
? ? ? spring是在何時加載到內存中的呢?
? ? ? ? ?springMvc是通過web.xml配置入口觸發,springboot是通過springApplication初始化觸發
?
?本次實現spring核心功能會涉及到哪些點?
? ? ? 1.注解的定義與使用
? ? ? 2.容器的初始化
? ? ? 3.配置文件的讀取與使用
? ? ? 4.sevlet的使用
? ? ? 5.注解的定義與使用
? ? ? 6.反射的運用
? ? ? 7.url路由與方法映射
? ? ? 8.參數解析與綁定
? ? ? 9.正則與轉義
?
?
?正式開始
? 首先創建一個maven項目,代碼結構如下:
?
添加jar包依賴:
里面有2個jar包加一個插件
javax.servlet-api.jar 用來啟動核心代碼和處理請求 fastjson.jar 用來做json參數綁定jetty-maven-plugin 使用jetty作為web容器啟動
完整maven代碼如下: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.honstat</groupId><artifactId>test-spring</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>4.0.1</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.56</version></dependency></dependencies><build><plugins><plugin><groupId>org.eclipse.jetty</groupId><artifactId>jetty-maven-plugin</artifactId><version>9.4.5.v20170502</version><configuration><scanIntervalSeconds>10</scanIntervalSeconds><webApp><contextPath>/</contextPath></webApp><httpConnector><port>8080</port></httpConnector></configuration></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.8</source><target>1.8</target></configuration></plugin></plugins></build> </project> View Code
?
?創建前端控制器類
? 前端控制器專門處理servlet請求,匹配到對應的方法執行后返回,前端控制器是什么可以參考我的另一篇博客《SpringMvc請求處理流程與源碼探秘》
? ?這里我們創建一個叫CJDispatcherServlet的類,它繼承HttpServlet類,并且重寫HttpServlet的init(),doGet(),doPost()?這3個方法,圖中的HomeService和StudentService可以先忽略不寫
?
?配置web.xml
?需要配置<servlet>?和<servlet-mapping> 2個標簽
<servlet>中需要
1.指定servlet名稱
?2.指定處理請求的前端控制器類
?3.設置初始化配置文件路徑
?
?完整web.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"version="2.5"><servlet><servlet-name>cjservletMVC</servlet-name><servlet-class>com.honstat.spring.service.CJDispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>spring/application.properties</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>cjservletMVC</servlet-name><url-pattern>/*</url-pattern></servlet-mapping> </web-app> View Code?
?添加注解
?我們知道,spring里面是通過給類加注解來識別各種使用場景的,那我們就來實現幾個必用的
作用在類上的:
??JCController
? JCService
? JCComponent
?
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) public @interface JCController {String value() default ""; }?全部采用這種類型
作用在方法上和類上的:
JCRequestMapping
@Documented @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.TYPE,ElementType.METHOD}) public @interface JCRequestMapping {String value() default ""; }?
作用在字段上的:
JCAutoWrited
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface JCAutoWrited {String value() default ""; }?
到此我們已經初步的創建完了需要準備的類,準備工作告一段落。
?由于篇幅有限,下一篇開始實現核心功能了!
?完整代碼地址
轉載于:https://www.cnblogs.com/jingch/p/11368982.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的自己实现spring核心功能 一的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 自己实现spring核心功能 二
- 下一篇: 反射,Expression Tree,I
