自始至終,SpringBoot框架都是為了能夠幫助使用Spring框架的開發 快速高效地構建 一個個基于Spring框架以及Spring生態體系的應用解決方案。要深刻理解SpringBoot框架,首先我們需要深刻理解Spring框架。
一、Spring 中的 IoC、DI 和 DL
部分Java開發者對 IoC 和 DI 的概念有些混淆,認為二者是對等的,實際IoC(Inversion Of Control——控制反轉)有兩種方式:
- 一種就是DI(Dependency Injection——依賴注入)是當前軟件實體被動接受其依賴的其他組件被IoC容器注入;
- 而另一種是DL(Dependency Lookup——依賴査找)是當前軟件實體主動去某個服務注冊地査找其依賴的那些服務。
概念之間的關系如圖所示
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MRnrEDuD-1614673450451)(…/…/Study notes/SpringBoot/notes/image/圖2-1 IOC相關概念示意圖.png)]
以一下Spring IoC容器的一個典型代碼片段為例
public class App (public static void main(String[] args) (Applicationcontext context = new FileSystemXmlApplication-Context("...");// ...MockService service = context.getBean(MockService.class); service.doSomething();)
)
任何一個使用Spring框架構建的獨立的Java應用,通常都會存在一行類似于context.getBean(..);
的代碼,實際上,這行代碼做的就是DL的工作,而構建的任何一種IoC容器背后(比如 BeanFactory或者ApplicationContext)發生的事情,則更多是DI的過程(也可能有部分DL的邏輯用于對接遺留系統)。
此外,Spring IoC容器的依賴注入工作可以分為兩個階段:
階段一:收集和注冊
第一個階段可以認為是構建和收集bean定義的階段,在這個階段中,我 們可以通過XML或者Java代碼的方式定義一些bean,然后通過手動組裝或者讓容器基于某些機制自動掃描的形式,將這些bean定義收集到IoC容器中。
階段二:分析和組裝
第二階段要干的事情就是分析這些已經在IoC容器之中的bean, 然后根據它們之間的依賴關系先后組裝它們。如果IoC容器發現某個bean依賴另一個bean,它就會將這另一個bean注入給依賴它的那個bean,直到所有 bean的依賴都注入完成,所有bean都“整裝待發”,整個IoC容器的工作即算完成。
二、JavaConfig 與 @Configuration
Java 5的推出,加上當年基于純Java Annotation的依賴注入框架Guice的 出現,使得Spring框架及其社區也“順應民意”,推出并持續完善了基于Java 代碼和Annotation元信息的依賴關系綁定描述方式,即JavaConfig項目
基于JavaConfig方式的依賴關系綁定描述基本上映射了最早的基于XML的配置方式,比如
-
表達形式層面
基于XML的配置方式是這樣的:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi= nhttp://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans. xsd http://www.springframework.org/schema/context http://www. springframework.org/schema/context/spring-context.xsd"> <!-- bean 定義--> </beans>
基于JavaConfig的配置方式是這樣的:
?Configuration public class MockConfiguration{// bean定義 }
任何一個標注了 ?Configuration的Java類定義都是一個JavaConfig配 置類。
-
注冊bean定義層面
基于XML的配置形式是這樣的:
<bean id= "mockService" class="..MockServicelmpl">... </bean>
而基于JavaConfig的配置形式是這樣的:
?Configuration public class MockConfiguration {@Beanpublic MockService mockService() {return new MockServiceJmpl();} }
任何一個標注了 @Bean的方法,其返回值將作為一個bean定義注冊到 Spring的IoC容器,方法名將默認成為該bean定義的id。
-
表達依賴注入關系層面
為了表達bean與bean之間的依賴關系,在XML形式中一般是這樣的:
<bean id= "mockService" class="..MockServicelmpl"><property name="dependencyService" ref="dependencyservice"/> </bean> <bean id="dependencyservice" class="DependencyServicelmpl"/>
而在JavaConhg中則是這樣的:
@Configuration public class MockConfiguration {@Beanpublic MockService mockService() {return new MockServiceImpl(dependencyservice());}@Beanpublic Dependencyservice dependencyservice() {return new DependencyServicelmpl();} }
如果一個bean的定義依賴其他bean,則直接調用對應JavaConfig類中依賴bean的創建方法就可以了。
三、其他高曝光率的Annotation
?Configuration在前面已經提及過了,這里不再贅述,下面看幾個其他比較常見的Annotation,便于為后面更好地理解SpringBoot框架
1、@ComponentScan
@ComponentScan
: 對應 XML 配置形式中的 context:component-scan
元 素
注解作用:@ComponentScan用于類或接口上主要是指定掃描路徑,spring會把指定路徑下帶有指定注解的類自動裝配到bean容器里。會被自動裝配的注解包括@Bean、@Controller、@Service、@Component、@Repository等等。
2、@lmport 與 @lmportResource
在XML形式的配置中,我們通過<import resource=,'XXX.xml"/>
的形式 將多個分開的容器配置合到一個配置中,在JavaConfig形式的配置中,我們則 使用@Import這個Annotation完成同樣目的:
@Configuration
?Import (MockConfiguration.class)
public class XConfiguration {...
}
@Import只負責引入JavaConfig形式定義的loC容器配置,如果有一些遺 留的配置或者遺留系統需要以XML形式來配置(比如dubbo框架),我們依然 可以通過@ImportResource將它們一起合并到當前JavaConfig配置的容器中:
@Configuration
@ImportResource("...")
public class XConfiguration {...
}
參考:
- 《SpringBoot揭秘+快速構建微服務體系》 第二章
- 淺析Spring IOC、依賴注入(DI)和依賴查找(DL)