開始以前:本文滿滿的圖片。請你們在閱讀以前準備好流量,以防爆表。哈哈。第一次寫IOC的文章,但願你們多多支持,謝謝。java
本文主要針對ClasspathXmlApplicationContext(還有與之相似的FileSystemXml...)的總體初始化流程作講解。若有疑問能夠加QQ羣: 77174608 來討論。web
主題開始:spring
讀源碼準備的環境:express
maven, logback基礎知識, Spring 相關使用經驗。springboot
進入正文: 首先開始pom.xmlapp
<properties> <spring.version>4.3.14.RELEASE</spring.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.springframework/spring-asm --> <!-- 注意,這裏是第一個坑,在高版本的spring中是不須要手動引入該依賴了,若是引入則會拋出 java.lang.IncompatibleClassChangeError: class org.springframework.core.type.classreading.ClassMetadataReadingVisitor has interface org.springframework.asm.ClassVisitor as super class 異常 --> <!--<dependency>--> <!--<groupId>org.springframework</groupId>--> <!--<artifactId>spring-asm</artifactId>--> <!--<version>3.1.4.RELEASE</version>--> <!--</dependency>--> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.21</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.1.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-expression</artifactId> <version>${spring.version}</version> </dependency> </dependencies>
logback配置:maven
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <logger name="org.springframework" additivity="false" level="debug"> <appender-ref ref="console"/> </logger>
我這裏使用了自動掃包,因此beans.xml配置爲:ide
<context:annotation-config/> <context:component-scan base-package="com.autorun.spring.demo"/>
ok, 環境已經基本已經搞定,咱們開始寫基本類this
package com.autorun.spring.demo.beans; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @author Autorun * Created by Autorun on 2018/3/4. */ @Component public class A { @Autowired private B b; @Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } A a = (A) o; return b != null ? b.equals(a.b) : a.b == null; } @Override public int hashCode() { return b != null ? b.hashCode() : 0; } @Override public String toString() { return "A{" + ", b=" + b + '}'; } }
package com.autorun.spring.demo.beans; import org.springframework.stereotype.Component; /** * @author Autorun * Created by Autorun on 2018/3/4. */ @Component public class B { }
而後建立主類(固然, 目前spring仍是主要用於web開發,有用過springboot的童鞋應該對這種玩法有所瞭解。再也不贅述):spa
public class Application { public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans-parent.xml"); ctx.setDisplayName("parent"); /// ctx.start(); A a = ctx.getBean(A.class); System.out.println(a); B b = ctx.getBean(B.class); System.out.println(b); }
以上就是環境準備篇。畢竟基礎。下一篇將正式開始源碼拆解。 前幾篇文章會粗略的走一遍加載,目的是讓你們熟悉一下總體流程。以後會對每一個組件進行講解。謝謝你們支持