spring總結(jié)
1、什么是Spring框架漱办,Spring框架主要包含哪些模塊
Spring是一個開源框架这刷,Spring是一個輕量級的Java 開發(fā)框架。它是為了解決企業(yè)應用開發(fā)的復雜性而創(chuàng)建的娩井。框架的主要優(yōu)勢之一就是其分層架構(gòu),分層架構(gòu)允許使用者選擇使用哪一個組件淋叶,同時為 J2EE 應用程序開發(fā)提供集成的框架码俩。Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。然而扬霜,Spring的用途不僅限于服務器端的開發(fā)定鸟。從簡單性、可測試性和松耦合的角度而言著瓶,任何Java應用都可以從Spring中受益联予。Spring的核心是控制反轉(zhuǎn)(IoC)和面向切面(AOP)。簡單來說材原,Spring是一個分層的full-stack(一站式)輕量級開源框架沸久。(需要這份資料可文末領取)
主要包含的模塊:
2余蟹、Spring框架的優(yōu)勢
1卷胯、Spring通過DI、AOP和消除樣板式代碼來簡化企業(yè)級Java開發(fā)
2威酒、Spring框架之外還存在一個構(gòu)建在核心框架之上的龐大生態(tài)圈窑睁,它將Spring擴展到不同的領域,如Web服務兼搏、REST卵慰、移動開發(fā)以及NoSQL
3、低侵入式設計佛呻,代碼的污染極低
4裳朋、獨立于各種應用服務器,基于Spring框架的應用,可以真正實現(xiàn)Write Once,Run Anywhere的承諾
5鲤嫡、Spring的IoC容器降低了業(yè)務對象替換的復雜性送挑,提高了組件之間的解耦
6、Spring的AOP允許將一些通用任務如安全暖眼、事務惕耕、日志等進行集中式處理,從而提供了更好的復用
7诫肠、Spring的ORM和DAO提供了與第三方持久層框架的的良好整合司澎,并簡化了底層的數(shù)據(jù)庫訪問
8、Spring的高度開放性栋豫,并不強制應用完全依賴于Spring挤安,開發(fā)者可自由選用Spring框架的部分或全部
3、IOC和DI是什么丧鸯?
控制反轉(zhuǎn)是就是應用本身不負責依賴對象的創(chuàng)建和維護,依賴對象的創(chuàng)建及維護是由外部容器負責的,這樣控制權(quán)就有應用轉(zhuǎn)移到了外部容器,控制權(quán)的轉(zhuǎn)移就是控制反轉(zhuǎn)蛤铜。
依賴注入是指:在程序運行期間,由外部容器動態(tài)地將依賴對象注入到組件中如:一般,通過構(gòu)造函數(shù)注入或者setter注入丛肢。
4围肥、描述下Spring IOC容器的初始化過程
spring核心接口
BeanFactory 頂層核心接口,規(guī)范子工廠蜂怎,生產(chǎn)bean BeanDefinition 封裝了一切用來生產(chǎn)bean方式
spring ioc穆刻、bean生命周期
spring 擴展點
就是我們程序員自己根據(jù)需要去實現(xiàn)的spring底層的擴展
BeanFactoryPostProcessor bean工廠后置處理器(可以用來修改bean定義的)
9個Bean的后置處理器
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors
MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation
InstantiationAwareBeanPostProcessor.postProcessPropertyValues
BeanPostProcessor.postProcessBeforeInitialization
BeanPostProcessor.postProcessAfterInitialization
DestructionAwareBeanPostProcessor.requiresDestruction
怎么看源碼?
1.把spring的項目源碼直接下過來編譯派敷。
new springApplication()
解析xml配置文件路徑
(AbstractApplicationContext#obtainFreshBeanFactory)
3.創(chuàng)建Bean工廠
4.加載bean定義到BeanDefinitionMap
5.調(diào)用了bean工廠的后置處理器:invokeBeanFactoryPostProcessors()
>org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
>org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
6.判斷是否符合生產(chǎn)標準(是不是抽象蛹批、懶加載、單例) >org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
7.真正的生產(chǎn)Bean, 去單例池中獲取看是否已經(jīng)創(chuàng)建篮愉,如果已經(jīng)創(chuàng)建則直接返回腐芍,如果單例池沒有就需要重新創(chuàng)建(為了解決循環(huán)依賴,將當前Bean加入到正在創(chuàng)建的標識中singletonsCurrentlyInCreation) >org.springframework.beans.factory.support.AbstractBeanFactory#createBean
8.可以使用Bean的后置處理器直接返回自定義的Bean實例
>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
9.調(diào)用doCreateBean開始真正創(chuàng)建Bean >org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance
10.實例化Bean(通過工廠方法试躏、Supplier猪勇、Bean后置處理器:
SmartInstantiationAwareBeanPostProcessor.determineCandidateConstructors,BeanDefinition的 ConstructorArgumentValues) 默認調(diào)用無參構(gòu)造函數(shù)來實例化
>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
11.注入屬性值
>org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
12.初始化Bean 調(diào)用Awea 調(diào)用@PostConstrut Aop的動態(tài)代理也是在初始完進行生成的
13.最終加入到單例池中
5颠蕴、BeanFactory 和 FactoryBean的區(qū)別泣刹?
BeanFactory是個Factory,也就是IOC容器或?qū)ο蠊S犀被,在Spring中椅您,所有的Bean都是由BeanFactory(也就是IOC容器)來進行管理的,提供了實例化對象和拿對象的功能寡键。
使用場景:
從Ioc容器中獲取Bean(byName or byType)
檢索Ioc容器中是否包含指定的Bean
判斷Bean是否為單例
FactoryBean是個Bean掀泳,這個Bean不是簡單的Bean,而是一個能生產(chǎn)或者修飾對象生成的工廠Bean,它的實現(xiàn)與設計模式中的工廠模式和修飾器模式類似。
facotryBean不是在spring上文加載的時候創(chuàng)建的员舵, 在getBean的時候創(chuàng)建的使用場景
ProxyFactoryBean
6脑沿、BeanFactory和ApplicationContext的異同
BeanFactory:spring 頂層核心接口,用來生產(chǎn)bean的.
相同:
Spring提供了兩種不同的IOC 容器马僻,一個是BeanFactory庄拇,另外一個是ApplicationContext,它們都是 Java interface韭邓,ApplicationContext繼承于BeanFactory(ApplicationContext繼承ListableBeanFactory措近。
它們都可以用來配置XML屬性,也支持屬性的自動注入仍秤。
BeanFactory 和 ApplicationContext 都提供了一種方式熄诡,使用getBean("bean name")獲取bean。
不同:
BeanFactory不支持國際化诗力,即i18n,但ApplicationContext提供了對它的支持我抠。
BeanFactory與ApplicationContext之間的另一個區(qū)別是能夠?qū)⑹录l(fā)布到注冊為監(jiān)聽器的bean苇本。
BeanFactory 的一個核心實現(xiàn)是XMLBeanFactory 而ApplicationContext 的一個核心實現(xiàn)是ClassPathXmlApplicationContext,Web容器的環(huán)境我們使用WebApplicationContext并且增加了 getServletContext 方法菜拓。
如果使用自動注入并使用BeanFactory瓣窄,則需要使用API注冊AutoWiredBeanPostProcessor,如果使用ApplicationContext纳鼎,則可以使用XML進行配置俺夕。
簡而言之,BeanFactory提供基本的IOC和DI功能贱鄙,而ApplicationContext提供高級功能劝贸,BeanFactory可用于測試和非生產(chǎn)使用,但ApplicationContext是功能更豐富的容器實現(xiàn)逗宁,應該優(yōu)于BeanFactory
7映九、Spring Bean 的生命周期?
總結(jié):
(1)實例化Bean:
對于BeanFactory容器瞎颗,當客戶向容器請求一個尚未初始化的bean時件甥,或初始化bean的時候需要注入另一個尚未初始化的依賴時,容器就會調(diào)用createBean進行實例化哼拔。對于ApplicationContext容器引有,當容器啟動結(jié)束后,通過獲取BeanDefinition對象中的信息倦逐,實例化所有的bean譬正。
(2)設置對象屬性(依賴注入):
實例化后的對象被封裝在BeanWrapper對象中,緊接著,Spring根據(jù)BeanDefinition中的信息以及通過BeanWrapper提供的設置屬性的接口完成依賴注入导帝。
(3)處理Aware接口:
接著守谓,Spring會檢測該對象是否實現(xiàn)了xxxAware接口,并將相關(guān)的xxxAware實例注入給Bean:
①如果這個Bean已經(jīng)實現(xiàn)了BeanNameAware接口您单,會調(diào)用它實現(xiàn)的setBeanName(String beanId)方法斋荞,此處傳遞的就是Spring配置文件中Bean的id值;
②如果這個Bean已經(jīng)實現(xiàn)了BeanFactoryAware接口虐秦,會調(diào)用它實現(xiàn)的setBeanFactory()方法平酿,傳遞的是Spring工廠自身。
③如果這個Bean已經(jīng)實現(xiàn)了ApplicationContextAware接口悦陋,會調(diào)用setApplicationContext(ApplicationContext)方法蜈彼,傳入Spring上下文;
(4)BeanPostProcessor:
如果想對Bean進行一些自定義的處理俺驶,那么可以讓Bean實現(xiàn)了BeanPostProcessor接口幸逆,那將會調(diào)用 postProcessBeforeInitialization(Object obj, String s)方法。(5)InitializingBean 與 init-method:
如果Bean在Spring配置文件中配置了 init-method 屬性暮现,則會自動調(diào)用其配置的初始化方法还绘。
(6)如果這個Bean實現(xiàn)了BeanPostProcessor接口,將會調(diào)用postProcessAfterInitialization(Object obj, String s)方法栖袋;由于這個方法是在Bean初始化結(jié)束時調(diào)用的拍顷,所以可以被應用于內(nèi)存或緩存技術(shù);以上幾個步驟完成后塘幅,Bean就已經(jīng)被正確創(chuàng)建了昔案,之后就可以使用這個Bean了。
(7)DisposableBean:
當Bean不再需要時电媳,會經(jīng)過清理階段踏揣,如果Bean實現(xiàn)了DisposableBean這個接口,會調(diào)用其實現(xiàn)的destroy()方法匆背;
(8)destroy-method:
最后呼伸,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調(diào)用其配置的銷毀方法钝尸。
8括享、Spring AOP的實現(xiàn)原理?
Spring AOP使用的動態(tài)代理珍促,所謂的動態(tài)代理就是說AOP框架不會去修改字節(jié)碼铃辖,而是在內(nèi)存中臨時為方法生成一個AOP對象,這個AOP對象包含了目標對象的全部方法猪叙,并且在特定的切點做了增強處理娇斩,并回調(diào)原對象的方法仁卷。
Spring AOP中的動態(tài)代理主要有兩種方式,JDK動態(tài)代理和CGLIB動態(tài)代理犬第。JDK動態(tài)代理通過反射來接收被代理的類锦积,并且要求被代理的類必須實現(xiàn)一個接口。JDK動態(tài)代理的核心是InvocationHandler接口和Proxy類歉嗓。
如果目標類沒有實現(xiàn)接口丰介,那么Spring AOP會選擇使用CGLIB來動態(tài)代理目標類。CGLIB(Code Generation Library)鉴分,是一個代碼生成的類庫哮幢,可以在運行時動態(tài)的生成某個類的子類,注意志珍,CGLIB是通過繼承的方式做的動態(tài)代理橙垢,因此如果某個類被標記為final,那么它是無法使用CGLIB做動態(tài)代理的伦糯。
9柜某、聲明式事務的優(yōu)缺點:
優(yōu)點:不需要在業(yè)務邏輯代碼中編寫事務相關(guān)代碼,只需要在配置文件配置或使用注解(@Transaction)舔株,這種方式?jīng)]有侵入性莺琳。
缺點:聲明式事務的最細粒度作用于方法上,如果像代碼塊也有事務需求载慈,只能變通下,將代碼塊變?yōu)榉椒ā?/p>
10珍手、Spring 的不同事務傳播行為有哪些办铡,干什么用的?
11琳要、Spring 中用到了那些設計模式寡具?
代理模式—在AOP中被用的比較多。
單例模式—在spring配置文件中定義的bean默認為單例模式稚补。
模板方法—用來解決代碼重復的問題童叠。比如. RestTemplate, JmsTemplate, JpaTemplate。
工廠模式—BeanFactory用來創(chuàng)建對象的實例课幕。
適配器--spring aop
裝飾器--spring data hashmapper
觀察者-- spring 事件驅(qū)動模型
回調(diào)--Spring Aware回調(diào)接口
12厦坛、Spring如何解決循環(huán)依賴?
https://juejin.cn/post/7085607089044717599
13乍惊、bean的作用域
(1)singleton:默認杜秸,每個容器中只有一個bean的實例,單例的模式由BeanFactory自身來維護润绎。
(2)prototype:為每一個bean請求提供一個實例撬碟。
(3)request:為每一個網(wǎng)絡請求創(chuàng)建一個實例诞挨,在請求完成以后,bean會失效并被垃圾回收器回收呢蛤。
(4)session:與request范圍類似惶傻,確保每個session中有一個bean的實例,在session過期后其障,bean會隨之失效银室。
14、Spring框架中有哪些不同類型的事件
(1)上下文更新事件(ContextRefreshedEvent):在調(diào)用ConfigurableApplicationContext 接口中的refresh()方法時被觸發(fā)静秆。
(2)上下文開始事件(ContextStartedEvent):當容器調(diào)用ConfigurableApplicationContext的Start()方法開始/重新開始容器時觸發(fā)該事件粮揉。
(3)上下文停止事件(ContextStoppedEvent):當容器調(diào)用ConfigurableApplicationContext的Stop()方法停止容器時觸發(fā)該事件。
(4)上下文關(guān)閉事件(ContextClosedEvent):當ApplicationContext被關(guān)閉時觸發(fā)該事件抚笔。容器被關(guān)閉時扶认,其管理的所有單例Bean都被銷毀。
(5)請求處理事件(RequestHandledEvent):在Web應用中殊橙,當一個http請求(request)結(jié)束觸發(fā)該事件辐宾。
15、Spring通知有哪些類型
(1)前置通知(Before advice):在某連接點(join point)之前執(zhí)行的通知膨蛮,但這個通知不能阻止連接點前的執(zhí)行(除非它拋出一個異常)叠纹。
(2)返回后通知(After returning advice):在某連接點(join point)正常完成后執(zhí)行的通知:例如,一個方法沒有拋出任何異常敞葛,正常返回誉察。
(3)拋出異常后通知(After throwing advice):在方法拋出異常退出時執(zhí)行的通知。
(4)后通知(After (finally) advice):當某連接點退出的時候執(zhí)行的通知(不論是正常返回還是異常退出)惹谐。(5)環(huán)繞通知(Around Advice):包圍一個連接點(join point)的通知持偏,如方法調(diào)用。這是最強大的一種通知類型氨肌。環(huán)繞通知可以在方法調(diào)用前后完成自定義的行為鸿秆。它也會選擇是否繼續(xù)執(zhí)行連接點或直接返回它們自己的返回值或拋出異常來結(jié)束執(zhí)行。環(huán)繞通知是最常用的一種通知類型怎囚。
16卿叽、Spring的自動裝配
在spring中,對象無需自己查找或創(chuàng)建與其關(guān)聯(lián)的其他對象恳守,由容器負責把需要相互協(xié)作的對象引用賦予各個對象考婴,使用autowire來配置自動裝載模式。
在Spring框架xml配置中共有5種自動裝配:
(1)no:默認的方式是不進行自動裝配的井誉,通過手工設置ref屬性來進行裝配bean蕉扮。
(2)byName:通過bean的名稱進行自動裝配,如果一個bean的 property 與另一bean 的name 相同颗圣,就進行自動裝配喳钟。
(3)byType:通過參數(shù)的數(shù)據(jù)類型進行自動裝配屁使。
(4)constructor:利用構(gòu)造函數(shù)進行裝配,并且構(gòu)造函數(shù)的參數(shù)通過byType進行裝配奔则。
(5)autodetect:自動探測蛮寂,如果有構(gòu)造方法,通過 construct的方式自動裝配易茬,否則使用 byType的方式自動裝配酬蹋。
基于注解的方式:
使用@Autowired注解來自動裝配指定的bean。在使用@Autowired注解之前需要在Spring配置文件進行配置抽莱, <context:annotation-config />范抓。在啟動spring IoC時,容器自動裝載了一個AutowiredAnnotationBeanPostProcessor后置處理器食铐,當容器掃描到@Autowied匕垫、@Resource或@Inject時,就會在IoC容器自動查找需要的bean虐呻,并裝配給該對象的屬性象泵。在使用@Autowired時,首先在容器中查詢對應類型的bean:
如果查詢結(jié)果剛好為一個斟叼,就將該bean裝配給@Autowired指定的數(shù)據(jù)偶惠;如果查詢的結(jié)果不止一個,那么@Autowired會根據(jù)名稱來查找朗涩;
如果上述查找的結(jié)果為空忽孽,那么會拋出異常。解決方法時谢床,使用required=false扒腕。
@Autowired可用于:構(gòu)造函數(shù)、成員變量萤悴、Setter方法
注:@Autowired和@Resource之間的區(qū)別
@Autowired默認是按照類型裝配注入的,默認情況下它要求依賴對象必須存在(可以設置它required屬性為false)皆的。
@Resource默認是按照名稱來裝配注入的覆履,只有當找不到與名稱匹配的bean才會按照類型來裝配注入。
最后
文章寫的如有不對之處還望指正费薄,如有需要文章所示資料可“點贊 收藏 關(guān)注”后私信小編領取硝全,最后祝大家好好學習,天天向上楞抡!