什么是spring
spring是一個(gè)輕量級(jí)的容器框架馋评,目的是簡(jiǎn)化企業(yè)應(yīng)用開發(fā),核心有兩大功能IOC和AOP,通過(guò)IOC可以幫助我們管理項(xiàng)目中對(duì)象依賴徘公,通過(guò)AOP可以幫助我們動(dòng)態(tài)增強(qiáng)應(yīng)用的功能性。spring對(duì)現(xiàn)有主流框架都有集成的支持哮针,讓我們我們很容易的在應(yīng)用中使用其他框架的功能关面。
什么是IOC
控制反轉(zhuǎn),IOC其實(shí)就是對(duì)象的生命周期交給spring管理十厢,spring本身是一個(gè)bean容器等太,幫助我們創(chuàng)建并且緩存對(duì)象引用,當(dāng)我們需要某個(gè)對(duì)象的時(shí)候蛮放,由spring進(jìn)行創(chuàng)建缩抡;過(guò)程中需要DI依賴注入,將我們需要的對(duì)象引用賦值給變量包颁,降低組件之間耦合性瞻想;對(duì)象與對(duì)象之間復(fù)雜的引用關(guān)系也由spring幫我們管理;第三方功能需要的對(duì)象也由spring幫我們管理娩嚼,我們只需要拿來(lái)即用就好蘑险。
什么是AOP
面向切面,切面指不同功能不同業(yè)務(wù)中相同的一部分邏輯岳悟,比如鑒權(quán)佃迄、日志、事務(wù)等模塊贵少,aop可以幫助我們輕易的在每個(gè)業(yè)務(wù)中進(jìn)行這些通用功能的拓展呵俏,讓我們只專注于實(shí)現(xiàn)業(yè)務(wù)功能即可。
當(dāng)你需要在很多方法或接口上增加相同或相似的邏輯時(shí)春瞬,可以考慮使用AOP柴信。
AOP有兩種實(shí)現(xiàn)方式Spring的實(shí)現(xiàn)和AspectJ的實(shí)現(xiàn),AspectJ是早期的aop實(shí)現(xiàn)宽气,定義了一些標(biāo)準(zhǔn)的枚舉随常,這些枚舉spring也在使用潜沦,AspectJ的實(shí)現(xiàn)方式是使用靜態(tài)代理增強(qiáng),在代碼編譯期間將切面邏輯織入對(duì)象绪氛;spring是通過(guò)動(dòng)態(tài)代理唆鸡,JDK或者CGlib,在對(duì)象創(chuàng)建期間枣察。
AOP中的概念
連接點(diǎn)(Join point) 被切入的執(zhí)行中的方法
切點(diǎn)(pointcut) 定義的一組被切入的方法
通知(advice) 在連接點(diǎn)上執(zhí)行的方法包括Around争占、Before、After序目、After returning臂痕、After throwing
切面(aspect) 被提取的公共模塊 切面就是一個(gè)pointcut + 一組advice
目標(biāo)對(duì)象(target) 包含連接點(diǎn)的對(duì)象
織入(Weaving) 通過(guò)代理等方法,在target的join point中執(zhí)行advice
AOP實(shí)現(xiàn)的方式
spring實(shí)現(xiàn)的AOP猿涨,動(dòng)態(tài)代理握童,jdk面向接口、cglib子類繼承叛赚,對(duì)象創(chuàng)建期間澡绩、getBean
AspectJ實(shí)現(xiàn)的AOP,靜態(tài)代理增強(qiáng)俺附,代碼編譯期間將切面邏輯織入對(duì)象
什么是spingmvc
springmvc是spring提供的web應(yīng)用框架肥卡,采用mvc模式modile-view-controller,springmvc本身是spring拓展出來(lái)的一個(gè)模塊事镣,spring對(duì)他提供很好的繼承支持步鉴,通過(guò)@Controller和@RequestMapping我們可以很簡(jiǎn)單的創(chuàng)建一個(gè)web接口,核心dispatcherservlet攔截所有請(qǐng)求蛮浑,根據(jù)uri找到對(duì)應(yīng)的handler方法并執(zhí)行唠叛,返回對(duì)應(yīng)視圖數(shù)據(jù)。
springmvc組件
- Handler Handler包裝了具體的業(yè)務(wù)邏輯沮稚,一個(gè)RequestMapping艺沼、servlet可以看做一個(gè)handler
- HandlerMapping 用來(lái)查找Hanlder,每個(gè)請(qǐng)求都由對(duì)應(yīng)的handler進(jìn)行處理蕴掏,reqeust找到HandlerExecutionChain障般,HandlerExecutionChain包含了一個(gè)Handler和一組Interceptors
- HandlerAdapter Handler適配器,用來(lái)適配項(xiàng)目中老的servlet候著controller盛杰,適配器模式挽荡,
- HandlerExceptionResolver 全局異常解析
- ViewResolver 視圖解析器,根據(jù)handler返回的ModleAndView找到對(duì)應(yīng)的頁(yè)面進(jìn)行渲染即供,可以是jsp定拟、html或者直接輸出
- MultipartResolver 處理上傳文件的請(qǐng)求,普通的request包裝成MultipartHttpServletRequest逗嫡,后者可以直接調(diào)用getFile方法獲取File
springmvc運(yùn)行原理
springmvc啟動(dòng)的時(shí)候會(huì)創(chuàng)建自己的上下文applicationcontext對(duì)象青自,將所有controller信息載入上下文株依,一個(gè)reqeustmapping就是一個(gè)contoller
- 客戶端請(qǐng)求提交到DispatcherServlet
- 由DispatcherServlet控制器查詢一個(gè)或多個(gè)HandlerMapping,找到處理請(qǐng)求的Controller
- DispatcherServlet將請(qǐng)求提交到Controller
- Controller調(diào)用業(yè)務(wù)邏輯處理后延窜,返回ModelAndView
- DispatcherServlet查詢一個(gè)或多個(gè)ViewResoler視圖解析器恋腕,找到ModelAndView指定的視圖
- 視圖負(fù)責(zé)將結(jié)果顯示到客戶端
springmvc中攔截器和過(guò)濾器的區(qū)別
過(guò)濾器是Servlet定義的規(guī)范、由servlet容器進(jìn)行實(shí)現(xiàn)逆瑞,攔截器是由springmvc定義并且實(shí)現(xiàn)的
過(guò)濾器在servlet之前調(diào)用荠藤,攔截器存儲(chǔ)在HandlerExecutionChain中,在DispatcherServlet中調(diào)用
過(guò)濾器攔截所有請(qǐng)求获高,攔截器只能攔截定義的handler
過(guò)濾器是責(zé)任鏈模式哈肖,攔截器是代理模式(靜態(tài)代理的)
什么是springboot
本質(zhì)上springboot還是spring,在spirng的基礎(chǔ)上做了一些更方便我們搭建項(xiàng)目的功能谋减,讓我們?cè)诰幋a牡彻、配置扫沼、部署出爹、監(jiān)控等方面變的更簡(jiǎn)單了。
基于約定大于配置的自動(dòng)裝配缎除,我們減少了很多配置項(xiàng)严就,starter幫助我們更簡(jiǎn)單的管理依賴,內(nèi)置servlet容器器罐,讓我們更快的啟動(dòng)部署一個(gè)應(yīng)用梢为。
什么是springcloud
springcloud是spring提出的一套關(guān)于微服務(wù)架構(gòu)的組件,包含網(wǎng)關(guān)轰坊、注冊(cè)中心铸董、配置中心、RPC肴沫、熔斷降級(jí)粟害、負(fù)載均衡、mq颤芬、分布式事務(wù)等組件
spring啟動(dòng)過(guò)程
spring的啟動(dòng)過(guò)程在AbstractApplicationContext.refresh()方法中執(zhí)行
- prepareRefresh(); 準(zhǔn)備上下文刷新 準(zhǔn)備一些集合容器
- *創(chuàng)建Bean工廠ConfigurableListableBeanFactory
- 在使用之前準(zhǔn)備一下BeanFactory內(nèi)部的一些信息 環(huán)境參數(shù)等
- *postProcessBeanFactory 允許子類對(duì)BeanFactory做一些后置處理悲幅,模板方法
- *invokeBeanFactoryPostProcessors 執(zhí)行Bean工廠后置處理器 會(huì)加載BeanDefinition
- *registerBeanPostProcessors 注冊(cè)Bean后置處理器
- initMessageSource 初始化消息源
- initApplicationEventMulticaster 初始化應(yīng)用事件廣播器
- *onRefresh 正在refresh,模板方法站蝠,交由子類實(shí)現(xiàn)汰具,ServletWebServerApplicationContext會(huì)在此處創(chuàng)建web服務(wù)器
- registerListeners 注冊(cè)觀察者們
- *finishBeanFactoryInitialization 根據(jù)BeanDefinition實(shí)例化所有Bean對(duì)象
- *finishRefresh 完成刷新 推送event消息,ServletWebServerApplicationContext重寫此方法菱魔,增加了啟動(dòng)web服務(wù)器的邏輯
beandefinition作用
beandefinition是Bean定義信息留荔,spring依靠beandefinition進(jìn)行實(shí)例化,在spring容器啟動(dòng)執(zhí)行invokeBeanFactoryPostProcessors方法時(shí)會(huì)掃描路徑上的所有Bean對(duì)象澜倦,加載他們的BeanDefinition信息到BeanFactory中聚蝶,后面會(huì)根據(jù)這些信息進(jìn)行Bean的實(shí)例化
springboot啟動(dòng)過(guò)程
- 實(shí)例化部分 new SpringApplication
從spring.factories文件中加載一些ApplicationContextInitializer拔疚、ApplicationListener;根據(jù)是否引用了某些class推測(cè)應(yīng)用類型既荚;設(shè)置一下運(yùn)行主類 - 啟動(dòng)部分
從spring.factories文件中加載SpringApplicationRunListener稚失,這個(gè)監(jiān)聽器是springboot啟動(dòng)過(guò)程的一些事件推送
創(chuàng)建ConfigurableApplicationContext上下文 這里會(huì)根據(jù)推測(cè)的應(yīng)用類型選擇創(chuàng)建對(duì)應(yīng)的子類實(shí)現(xiàn)
準(zhǔn)備上下文 加載一些環(huán)境信息、啟動(dòng)參數(shù)信息等
執(zhí)行上下文刷新啟動(dòng)spring
執(zhí)行結(jié)束
spring中bean加載過(guò)程
實(shí)例化Bean 通過(guò)反射調(diào)用class的構(gòu)造方法或者通過(guò)@Bean設(shè)置的實(shí)例化方法 此時(shí)Bean對(duì)象所有屬性都是默認(rèn)值
為Bean對(duì)象進(jìn)行屬性填充 這個(gè)階段會(huì)遇到循環(huán)依賴問(wèn)題 注入自定義對(duì)象
為Bean對(duì)象填充awera信息 注入上下文對(duì)象
執(zhí)行BeanPostProcessor前置方法
執(zhí)行init方法
執(zhí)行BeanPostProcessor后置方法
將Bean放入BeanFactory
所有BeanPostProcessor都會(huì)在aware之后執(zhí)行么
有一些BeanPostProcessor會(huì)提前到populateBean階段執(zhí)行
AOP恰聘、Autowaire句各、dubbo的Refrence
InstantiationAwareBeanPostProcessor
DestructionAwareBeanPostProcessor
MergedBeanDefinitionPostProcessor
spring解決循環(huán)依賴
spring循環(huán)依賴問(wèn)題:spring中交由BeanFactory創(chuàng)建Bean對(duì)象,而創(chuàng)建Bean對(duì)象過(guò)程中有可能依賴了其他對(duì)象也需要?jiǎng)?chuàng)建晴叨,如果兩個(gè)對(duì)象互相依賴那么創(chuàng)建過(guò)程就會(huì)進(jìn)入一個(gè)死循環(huán)凿宾;單緩存無(wú)法解決,是因?yàn)閷?duì)象沒(méi)有創(chuàng)建完畢就放入緩存是不安全的兼蕊;雙緩存可以解決初厚,但是對(duì)于aop無(wú)法處理,spring實(shí)現(xiàn)aop是在BeanPostProcessor階段孙技,如果強(qiáng)行處理就需要把a(bǔ)op提前到Bean實(shí)例化階段产禾,侵入了標(biāo)準(zhǔn)Bean的創(chuàng)建;三級(jí)緩存解決aop動(dòng)態(tài)代理問(wèn)題
解決方法:
A對(duì)象實(shí)例化之后創(chuàng)建一個(gè)ObjectFactory放入三級(jí)緩存牵啦,ObjectFactory是一段lambda表達(dá)式亚情,執(zhí)行了獲取A對(duì)象最終引用的代碼,過(guò)程中執(zhí)行一些BeanPostProcessor處理包括AOP哈雏;
A對(duì)象屬性填充階段加載B對(duì)象楞件,實(shí)例化B對(duì)象之后也放入三級(jí)緩存,進(jìn)入B的屬性填充裳瘪,B的屬性填充階段需要加載A對(duì)象土浸,從三級(jí)緩存取出對(duì)象引用放入二級(jí)緩存,并執(zhí)行屬性填充彭羹;
B屬性填充等一些列代碼執(zhí)行完畢后黄伊,將B對(duì)象的從三級(jí)緩存取出放入一級(jí)緩存;
A對(duì)象拿到B的引用皆怕,進(jìn)行屬性填充完畢毅舆,從二級(jí)緩存出去放入一級(jí)緩存
springmvc父子容器
springmvc啟動(dòng)的時(shí)候,加載DispatcherServlet的時(shí)候會(huì)再創(chuàng)建一個(gè)ApplictionContext愈腾,并將Spring已經(jīng)創(chuàng)建的向下文設(shè)置為父級(jí)憋活,形成父子容器
父子容器的存在主要是為了劃分邊界,service層我們使用spring框架虱黄,對(duì)象功能由spring幫我們管理悦即,而在web層可能存在多實(shí)現(xiàn),比如springmvc struts2,父子容器可以幫助我們很容易的替換web層辜梳,只需要將spring-servlet.xml替換成Struts的配置文件struts.xml粱甫,service層都不用動(dòng)。
控制掃描路徑作瞄,來(lái)規(guī)避父子容器掃描的Bean對(duì)象
SpringBoot中使用的是同一個(gè)容器茶宵,將DispatcherServlet作為一個(gè)Bean對(duì)象交由Spring啟動(dòng)了,以前是交由tomcat啟動(dòng)宗挥。
springmvc常用注解
@Controller 標(biāo)記是一個(gè)contoller
@RequestMapping 標(biāo)記資源路徑
@RequestParam 標(biāo)記參數(shù)名稱乌庶,必填
@RequestAttribute 標(biāo)記屬性名稱,必填
@RequestBody 標(biāo)記參數(shù)是Json體
@ResponseBody 標(biāo)記返回時(shí)Json體
@RestController 標(biāo)記controller內(nèi)部全是json方法
@WebFilter 過(guò)濾器
@CrossOrigin 標(biāo)記請(qǐng)求與
spring加載bean的幾種方式
@Component
@Configuration
<bean/>
@Bean
<import/>
@Import
ImportSelector接口
ImportBeanDefinitionRegistrar接口
springboot自動(dòng)裝配原理
springboot自動(dòng)為我們創(chuàng)建一些Bean對(duì)象契耿,基于約定大于配置的原則瞒大,按照默認(rèn)值去創(chuàng)建。
@SpringBootApplication修飾了啟動(dòng)類搪桂,@SpringBootApplication包含@EnableAutoConfiguration
@EnableAutoConfiguration包含@Import(AutoConfigurationImportSelector.class)
所有需要自動(dòng)裝配的類是依靠AutoConfigurationImportSelector透敌,從spring.factories文件中加載所有配置為EnableAutoConfiguration的類
裝配時(shí)機(jī)是在啟動(dòng)時(shí),context.refresh()中踢械,執(zhí)行BeanFacotoryPostProcessor階段酗电,通過(guò)ConfigurationClassPostProcessor加載
springboot內(nèi)嵌tomcat原理
- SpringApplication在實(shí)例化階段會(huì)根據(jù)路徑上引用的一些class推測(cè)當(dāng)前應(yīng)用的類型,如果存在Servlet或者ConfigurableWebApplicationContext會(huì)被推測(cè)為是一個(gè)web服務(wù)器裸燎;
- SpringApplication.run階段創(chuàng)建上下文時(shí)顾瞻,會(huì)根據(jù)上面推測(cè)的應(yīng)用類型創(chuàng)建具體的上下文,這里會(huì)創(chuàng)建AnnotationConfigServletWebServerApplicationContext
- 這個(gè)context在refresh階段的onRefresh中會(huì)創(chuàng)建webServer德绿,默認(rèn)是tomcat,加載的ServletWebServerFactory默認(rèn)是tomcat的退渗,根據(jù)是否引用了內(nèi)置tomcat其他的還有jetty移稳、Undertow
TomcatServletWebServerFactory是通過(guò)ServletWebServerFactoryAutoConfiguration自動(dòng)裝配的,條件是路徑上有Tomcat会油、Servlet - 在refresh階段的finishRefresh中會(huì)啟動(dòng)webServer
spring和springboot中提供了哪些擴(kuò)展點(diǎn)
BeanFactoryPostProcessor Bean工廠后置處理器 可以通過(guò)ApplicationContextInitializer加載个粱,或者只要在refresh方法之前通過(guò)listener加載
BeanPostProcessor Bean后置處理器
ApplicationRunListener 廣播springboot啟動(dòng)事件
ApplicationListener 廣播spring啟動(dòng)事件
ApplicationContextInitializer在什么時(shí)機(jī)執(zhí)行
SpringApplication.run.prepareContext;
springboot的starter原理
管理依賴,省去了以前引入一大堆依賴翻翩,還要梳理版本都许,弄不好就會(huì)沖突,
自動(dòng)裝配組件嫂冻,省去了一大堆配置
統(tǒng)一配置文件胶征,將所有配置統(tǒng)一到spring的配置文件中,便于管理
手寫starter
一般分為兩個(gè)包 一個(gè)starter包負(fù)責(zé)引入依賴桨仿,一個(gè)autoconfiguration包負(fù)責(zé)自動(dòng)裝配組件
starter包不需要任何代碼睛低,只引入依賴
autoconfiguration包定義配置類,定義組件Bean,自動(dòng)裝配
配置文件類:使用@ConfigurationProperties(prefix = "demo")修飾的Java類钱雷,屬性名就是配置名
自動(dòng)配置類:@EnableConfigurationProperties(DemoProperties.class)修飾的Java類骂铁,會(huì)自動(dòng)讀取spring配置文件中對(duì)應(yīng)配置信息
定義組件:完成核心業(yè)務(wù),并用@Bean等方式定義為一個(gè)Bean對(duì)象
自動(dòng)裝配:在META-INF目錄下添加spring.factories罩抗,并配置org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx.DemoAutoConfiguration
BeanFactory和ApplicationContext
BeanFactory是bean工廠拉庵,ApplicationContext是應(yīng)用上下文
ApplicationContext實(shí)現(xiàn)了BeanFactory通過(guò)門面模式支持了BeanFactory中的方法,內(nèi)部引用了一個(gè)DefaultListabledBeanFactory
ApplicationContext還負(fù)責(zé)整個(gè)應(yīng)用的生命周期套蒂,BeanFactory只管Bean對(duì)象
BeanFactory和FactoryBean
BeanFactory是bean工廠名段,簡(jiǎn)單工廠模式;
FactoryBean是一個(gè)Bean泣懊,工廠方法模式伸辟,getBean方法中對(duì)其特殊處理,如果是FactoryBean實(shí)現(xiàn)類并且非急切加載的話馍刮,會(huì)后置處理信夫,當(dāng)獲取FactoryBean時(shí)會(huì)自動(dòng)調(diào)用getOBject方法,如果需要FactoryBean對(duì)象卡啰,需要getBean("&"+name)静稻,用于懶加載對(duì)象,或加載復(fù)雜對(duì)象實(shí)現(xiàn)匈辱,比如
spring中的設(shè)計(jì)模式
Listener 觀察者模式
HandlerAdapter 適配器模式
AOP 代理模式
ApplicationContext 門面模式
AbstractApplicationContext.refresh() 模板方法
BeanFactory 簡(jiǎn)單工廠
FactoryBean和ObjectBean 工廠方法
Waraper 裝飾模式
springcloud有哪些組件
網(wǎng)關(guān) 配置中心 注冊(cè)中心 服務(wù)調(diào)用RPC 負(fù)載均衡 熔斷降級(jí) 限流 路由 分布式消息 分布式事務(wù)
spring中的事務(wù)
基于AOP + Threadlocal實(shí)現(xiàn)
spring中的事務(wù)傳播
required 如果存在就加入振湾,如果沒(méi)有就創(chuàng)建
supports 如果存在就加入,如果沒(méi)有就非事務(wù)執(zhí)行
not_supports 如果存在就掛起亡脸,非事務(wù)執(zhí)行
required_new 如果存在就掛起押搪,開啟一個(gè)新事物執(zhí)行
mandatory 如果不存在事務(wù),拋異常
never 如果存在事務(wù)浅碾,拋異常
nested 嵌套事物大州,子事務(wù)不影響父,父回滾垂谢,子回滾
spring中事務(wù)失效的場(chǎng)景
私有方法厦画、final方法、多線程調(diào)用滥朱、非spring管理對(duì)象根暑、直接調(diào)用、吞異常徙邻、數(shù)據(jù)庫(kù)不支持事務(wù)排嫌、
@Resouce和@Autowire的區(qū)別
resouce getBeanByName J2ee注解
autowire getBeanByType spring注解 配合@Qualifier根據(jù)name加載;可以裝配多個(gè)實(shí)例到集合或者map