Spring的豐富功能都是基于其兩大核心特性:
- 控制翻轉(IOC)/依賴注入(Dependency Injection伺帘,DI)
- 面向切面編程(Aspect-Oriented Programming, AOP)
IOC/DI容器解決了對象的創(chuàng)建,及對象之間的裝配忌锯。使得應用組件不再需要顯式創(chuàng)建和管理其依賴的組件,只需要聲明自己依賴的組件即可偶垮。而依賴組件的創(chuàng)建和注入則交給了IOC/DI容器张咳。
通過DI,對象的依賴關系將由系統(tǒng)中的負責協(xié)調(diào)各對象的第三方組件在創(chuàng)建對象的時候進行設定似舵。
1. DI--降低耦合脚猾、整潔、易理解砚哗、易測試
通常應用由多個相互協(xié)作的組件共同完成業(yè)務邏輯龙助。按傳統(tǒng)做法,組件負責創(chuàng)建其依賴的對象频祝,并管理其依賴的對象的引用泌参,這會導致組件類和依賴的緊耦合。
而使用了IOC/DI容器后常空,組件類通過(1)依賴接口(而不是具體實現(xiàn))沽一,以及(2)將依賴的創(chuàng)建交給容器,使得組件類不再依賴于具體實現(xiàn)漓糙,從而實現(xiàn)組件類和其依賴對象的解耦(組件類的import中只有依賴的接口铣缠,沒有依賴接口的具體實現(xiàn)),并且組件類的代碼也變得更加整潔昆禽。
將依賴的創(chuàng)建分離出來后蝗蛙,依賴的創(chuàng)建方式的變化也不會影響到組件類,使得依賴類更容易變更醉鳖。
另外捡硅,使組件類依賴接口,也使得測試更加容易盗棵,組件類和其依賴類可以分開測試壮韭。
2. Spring IOC容器
2.1 應用對象由Spring容器管理
在基于Spring的應用中北发,你的應用對象生存于Spring容器中。
Spring容器負責創(chuàng)建喷屋、裝配對象琳拨,并管理對象從生存到死亡的整個生命周期。
可以通過配置來告訴容器如何創(chuàng)建和組裝對象屯曹。
2.2 Spring的容器類別和常用容器
Spring容器可以分為兩類:Bean工廠 和 應用上下文狱庇。
Bean工廠(BeanFactory)
org.springframework.beans.factory.BeanFactory 提供Bean的創(chuàng)建、獲取等基本功能恶耽,還提供BFPP密任、BPP等擴展。應用上下文 (ApplicationContext)
org.springframework.context.ApplicationContext 基于BeanFactory構建驳棱,提供應用框架級服務批什,在Bean基礎上增加了事件發(fā)布农曲、消息源等功能社搅。
常用應用上下文類:
AnnotationConfigurationApplicationContext 、AnnotationConfigurationWebApplicationContext:
從一個或多個基于Java的配置類中加載Spring上下文乳规。(推薦方式)配置類經(jīng)常會使用@ComponentScan實現(xiàn)組件自動掃描形葬。ClasspathXmlApplicationContext、XmlWebApplicationContext:
從一個或多個基于Xml的配置文件中加載Spring上下文暮的。
2.3 容器中Bean的生命周期
根據(jù)AbstractApplicationContext的refresh()函數(shù)笙以,可以得到容器中Bean的聲明周期。主要包括如下階段(包含Bean創(chuàng)建前的處理):
// 忽略了無關代碼
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 實例化階段冻辩!
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 屬性賦值階段猖腕!
populateBean(beanName, mbd, instanceWrapper);
// 初始化階段!
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
1. Bean工廠后處理(invokeBeanFactoryPostProcessors):
- 實例化并執(zhí)行 BeanFactoryPostProcessor.postProcessBeanFactory() 方法
2. Bean實例化(Instantiation):
- 應用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
- 實例化Bean(createBeanInstance)
3. 屬性填充(populateBean)
- 應用InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
- 填充值或依賴
4. 初始化(initializeBean)
- 順序調(diào)用Aware方法
- 應用BeanPostProcessor.postProcessBeforeInitialization
- 執(zhí)行初始化方法(順序如下)
- @PostConstruct
- InitializingBean.afterPropertiesSet()
- 自定義"init"方法
- 應用BeanPostProcessor.postProcessAfterInitialization
5. 銷毀
- 執(zhí)行銷毀方法(順序如下)
- @PreDestroy
- DisposableBean.destroy()
- 自定義"destroy"方法
參考《Spring實戰(zhàn)第4版》
http://www.reibang.com/p/1dec08d290c1(請別再問Spring Bean的生命周期了:奚痢)
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-lifecycle-combined-effects (初始化倘感、銷毀方法執(zhí)行順序)