如何看Spring源碼


想要深入的熟悉了解Spring源碼,我覺得第一步就是要有一個能跑起來的極盡簡單的框架,下面我就教大家搭建一個最簡單的Spring框架,而且是基於Java Config形式的零配置Spring框架。

首先第一步創建一個空的maven web項目,這步很簡單,自行百度。

在maven項目的pom.xml文件中添加Spring基礎依賴:

<properties>
            <spring.version>4.3.7.RELEASE</spring.version>
            <slf4j.version>1.7.21</slf4j.version>
            <log4j.version>2.8.2</log4j.version>
            <logging.version>1.2</logging.version>
        </properties>

        <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <version>${spring.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
        </dependency>

        <!-- log配置:Log4j2 + Slf4j -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-web -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency> <!-- 橋接:告訴Slf4j使用Log4j2 -->
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency> <!-- 橋接:告訴commons logging使用Log4j2 -->
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-jcl</artifactId>
            <version>${log4j.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>${slf4j.version}</version>
        </dependency>

    </dependencies>

我推薦搭建基於Java Config形式的Spring框架,不需要配置文件,全部使用Java代碼形式來定義,簡潔明了,對於想要深入了解Spring源碼來說這點很重要,否則可能需要看非常多的Spring解析XML配置文件的解析類,對於任何人都不是很容易的功夫。而使用Java Config形式能直接看到配置類的運行流程,對了解Spring源碼很有幫助。

要搭建基於Java Config形式的Spring框架,要求Servlet-api版本3.0以上,同時推薦Spring版本4.0以上,日志可以使用我另一篇博客上的log4j2的配置,自己修改下輸出日志文件路徑就可以了。

public class WebContextInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] {RootContextConfig.class};
    }
}

@Configuration
@ComponentScan
public class RootContextConfig {
    @Bean
    public Child child() {
        return new Child();
    }
}
public class Child {
}

@Component
public class Mother {
}

把這幾個類都放在一個包下,然后啟動tomcat,應該就可以啟動Spring了,這就是一個最基本的Spring框架,而且包含了Java Config的Bean的定義以及組件掃描,RootContextConfig這個類就是容器的配置類,之后就可以開始跟着Spring框架的啟動流程看了,DEBUG跟着一步一步的走。

WebContextInitializer 的父類的將RootContextConfig 當做配置類生成一個AnnotationConfigWebApplicationContext 

類型ApplicationContext容器,注入到ContextLoaderListener中。 

......
    protected WebApplicationContext createRootApplicationContext() {
        Class<?>[] configClasses = getRootConfigClasses();
        if (!ObjectUtils.isEmpty(configClasses)) {
            AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
            rootAppContext.register(configClasses);
            return rootAppContext;
        }
        else {
            return null;
        }
    }
    ......
    protected void registerContextLoaderListener(ServletContext servletContext) {
        WebApplicationContext rootAppContext = createRootApplicationContext();
        if (rootAppContext != null) {
            ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
            listener.setContextInitializers(getRootApplicationContextInitializers());
            servletContext.addListener(listener);
        }
        else {
            logger.debug("No ContextLoaderListener registered, as " +
                    "createRootApplicationContext() did not return an application context");
        }
    }

不要對Tomcat內的源碼花時間,主要是看Spring的源碼,之后就可以看ContextLoaderListener的contextInitialized(…)方法了,Spring容器就是在這個方法里初始化生成的。如何初始化,這個太復雜了,需要花非常多的時間去看,去思考的,這里就不講了,不過我可以說一些我自己總結的小技巧:

 

說是看源碼,其實應該叫看和想。Spring源碼很復雜,我覺得花在思考上的時間至少要和看的時間對等。看了,如果沒有花時間想明白,等於白看。

理解重於記憶。Spring的流程很長,東西很多,如果單純靠記憶肯定記不過來的,知道每個組件的大體作用以及作用的節點就夠了,源碼就在那里,又不會跑,記不清了翻翻就看到了,多翻幾次就能夠慢慢記住了,最開始看的時候不要執着於記憶。

多做筆記。Spring組件很多,在最開始看的時候,推薦做些筆記,將每個重要接口的作用及關鍵代碼記錄下,有時間就看看,最先了解的組件是你切入Spring源碼的切口,借助他們能關聯到其他的組件。

多百度。在看一些關鍵接口或者類時,如果其代碼很復雜,先百度下吧,先對其功能有個了解,然后對照着功能看代碼會有很大的幫助。

要多遍地看,反復地看。別想着看一遍就能看明白,在最開始的幾次跟着初始化流程看源碼時,不要執着於某個細節。先對Spring所有的組件功能有個大體了解,對初始化流程有個大體的了解,這是深入的基礎。

多看日志,多DEBUG。多看日志能夠提高你對Spring流程的了解程度,而且在排錯時能有效提高效率;DEBUG是看源碼最好的一種方式,是解疑的最直接途徑,對於有些運行時難以觸及的代碼,需要你手動創造條件讓流程走入此處。

多總結,多動手。不要僅局限於看和思考,要動手。源碼看的仔細,基本能從源碼上看出很多Spring組件的使用方式,總結各種組件的使用方法,然后自己定義相應的組件,將其引入Spring中,查看其作用流程,這是你拓展Spring的第一步,既能增強對Spring的理解,也能提高你對Spring的拓展能力。

不斷完善框架。每熟悉一種組件的使用,就添加到自己的 框架中,不斷完善自己的框架,到最后你的框架能夠整合Spring大部分好用組件,也是你以后回顧Spring框架的最大助力。

多看注釋,看方法的名稱,參數和返回值。看注釋,理解類,屬性和方法的作用,着重第一段注釋;看方法的名稱,參數和返回值能對方法的作用有很明顯的說明。

 

以上就是我自己看Spring總結的一些小技巧,希望對你們有些助益。

 

后面持續更新相關文章,敬請期待!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM