天天看點

Spring面試題大全

spring面試題

1、什麼是Spring架構?

spring是分層 的全棧輕量級開源架構,以Ioc和Aop為核心思想,提供了展現層Springmvc和業務層事務管理器等衆多企業級應用技術,還能整合開源世界衆多著名三方架構和類庫的java開源架構。      

2、列舉一些重要的Spring子產品?

Spring是一個分層非常清晰并且依賴關系、職責定位非常明确的輕量級架構。
主要包括這幾大子產品:資料處理子產品,Web子產品,Aop/Aspect子產品,Core Container子產品和Test子產品。      

3、談談自己對Spring Ioc和Aop的了解?

1)、Ioc的了解
Ioc叫做控制反轉,它是一個技術思想,不是一個技術實作。
描述了java開發領域對象的建立和管理的問題
為什麼叫控制反轉?控制指的是對象的建立和管理的權利,反轉指的是控制的權利交給了外部環境(SpringIoc)。
Ioc和DI描述的是同一個事情(對象執行個體化和依賴關系維護),隻不過角度不一樣罷了。
Ioc是站在對象的角度,對象執行個體化和依賴維護的權利交給了(反轉)容器。
DI是站在容器的角度,容器會把對象的依賴的其他對象注入。
2)、Aop的了解
Aop叫做面向切面程式設計,Aop是OOP的延續。OOP使用封裝、繼承和多台解決了大多數的代碼重複問題。
但有些情況處理不了(頂級父類中的多個方法出現相同的代碼,稱為橫切邏輯相同)。
AOP為獨辟蹊徑日出抽取機制,在不改變原有邏輯情況下,增強代碼邏輯,從根本上上解耦。
為什麼叫做面向切面程式設計?切:指橫切邏輯,面:橫切邏輯一般影響多個方法,每個方法如同一個點,多個點構成面。      

4、Spring Aop和AspectJ Aop有什麼差別?

SpringAop是運作時增強,是基于代理實作的,AspectJ是編譯時增強,是基于位元組碼操作。      

5、Spring中的bean的作用域有哪些?

單例:singleton
多例:prototype
reuqest:一次request内有效
Session:同一個session有效
global-session:全局session,spring5中已廢棄      

6、Spring中的單例bean的線程安全問題了解嗎?

單例Bean存線上程安全問題,多線程操作同一個單例的成員變量進行寫操作時存線上程安全問題。
解決:使用将成員變量定義在ThreadLocal中。      

7、Spring架構中用到了哪些設計模式?

工廠模式:通過BeanFactory和ApplicationContext建立bean對象
代理模式:SpringAop和事務管理
單例模式:Spring中的Bean預設時單例
模闆方法:jdbcTemplate等
觀察者模式:Spring事件驅動模型就是觀察者模式
擴充卡模式:多種資料庫連接配接使用擴充卡,SpringMVC使用處理器擴充卡去擷取對應的具體處理器。      

8、@Component和@Bean的差別?

作用對象不同,@Component作用于類,@Bean作用于方法
@Component注解通常是通過類路徑掃描自動裝配到Ioc容器的,@Bean注解是在方法中産生,當我們需要是才執行個體化。
@Bean注解比@Component注解的自定義性更強,而且很多地方隻能通過@Bean注解來注冊bean。      

9、将一個類聲明為Spring Bean的注解有哪些?

@Component,@Service,@Repository,@Controller      

10、Spring事務管理的方式有幾種?

聲明式事務和程式設計式事務      

11、Spring中的事務隔離級别有哪幾種?

ISOLATION_DEFAULT
使用資料庫預設隔離級别,Mysql預設采用可重複讀隔離級别,Oracle預設采用讀已送出

ISOLATION_READ_UNCOMMITTED
讀未送出,最低隔離界别,可能導緻髒讀,幻讀和不可重複讀

ISOLATION_READ_COMMITTED
讀已送出,允許讀取并發事務已經送出的資料,可避免髒讀,幻讀和不可重複讀可能發生

ISOLATION_REPEATABLE_READ
可重複度,可避免髒讀,不可重複讀,可能發生幻讀

ISOLATION_SERIALIZABLE
串行化,最高隔離界别,但是性能低下。      

12、Spring事務中有哪幾種事務傳播行為?

PROPOGATION_REQUIRED
如果目前存在事務,則加入該事務,沒有則建立

PROPOGATION_SUPPORTS
如果存在事務,加入,不存在,非事務執行      

13、BeanFactory和ApplicationContext有什麼差別?

BeanFactory是SpringIoc的頂層接口,隻定義了基礎規範。ApplicationContext是它的子接口,具備BeanFactory的全部功能。

BeanFactory是SpringIoc的基礎容器,ApplicationContext是容器的進階接口。擁有更多的功能,比如國際化,資源通路等      

14、BeanFactory和FactoryBean的差別?

BeanFactory是容器得頂層接口,定義了一些基礎行為,是負責生産和管理bean得一個工廠。

FactoryBean是Spring中得一種特殊的工廠Bean,可以生成某一類型的Bean執行個體,也就是說,可以使用Factory Bean自定義Bean的建立過程。

FactoryBean接口方法
    T getObject() 傳回FactoryBean建立Bean的執行個體,如果isSingleton傳回true,降入放入單例池。

    getObjectType() 傳回FactoryBean建立的Bean類型

    isSingleton() 傳回作用于是否單例      

15、描述一下Spring Ioc的初始化過程?

(1)、源碼

(2)、初始化過程分析

第一步:調用prepareRefresh()做重新整理前的預處理工作

第二步:調用obtainFreshBeanFactory()擷取BeanFactory,預設實作時DefaultListableBeanFactory,加載BeanDefinition并注冊到BeanDefinitionRegist
ry中

第三步:調用prepareBeanFactory()方法對BeanFactory做一些前置準備工作,比如設定context的類加載器等

第四步:調用postProcessorBeanFactory對BeanFactory做一些後置處理

第五步:調用invokeBeanFactoryPostProcessors()使用反射技術調用實作了BeanFactoryPostProcessor接口的Bean

第六步:調用registerBeanPostProcessors()注冊BeanPostProcessor(Bean的後置處理器),在Bean的建立前後執行

第七步:調用initMessageSource()初始化MessageSource(做國際化、消息綁定,消息解析等)

第八步:調用initApplicationEventMulticaster()初始化事件派發器

第九步:調用onRefresh()方法,子類将會重寫該方法,在重新整理時可以自定義邏輯

第十步:調用registerListeners()注冊實作了ApplicationListener接口的Bean

第十一步:調用finishBeanFactoryInitialization()執行個體化所有沒有設定懶加載的單例Bean 比如填充屬性,調用初始化方法(比如調用afterPropertiesSet(),init-method等),調用BeanPostProcessor對Bean進行後置處理

第十二步:調用finishRefresh()完成對context的重新整理      

16、談一談BeanFactory是如何建立的?

第一步:調用refreshBeanFactory()重新整理BeanFactory
  調用AbstractRefreshableApplicationContext的createBeanFactory()建立 BeanFactory
        1、判斷是否已經有了BeanFactory,有則銷毀Bean并關閉BeanFactory
        2、沒有則調用createBeanFactory()方法建立BeenFactory并設定一些屬性
        3、調用loadBeanDefinitions()加載應用中的BeanDefinition,會一直調用到XmlBeanDefinitionReader的doLoadBeanDefinitions()方法
            1、調用doLoadDocument()方法讀取xml,将xml中的資訊儲存到Document中
            2、調用registerBeanDefinitions()解析document對象,封裝BeanDefinition并進行注冊
                1、一直調用下去會調用到DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions()方法
                2、繼續調用parseBeanDefinitions()方法後再調用parseDefaultElement()方法
                3、根據Xml的節點名稱為bean後調用processBeanDefinition方法進行解析
                    1、解析為BeanDefinitionHolder對象,是一個BeanDefinition的包裝類型
                    2、使用BeanDefinitionReaderUtils工具類完成BeanDefinition的注冊
第二步:調用getBeanFactorty()擷取BeanFactory,實際傳回一個DefaultListableBeanFactory      

17、談一談Spring Bean是如何建立的?

第一步:進入入口方法AbstractApplicationContext的finishBeanFactoryInitialization()方法

第二步:調用DefaultListableBeanFactory(也就是上面obtainBeanFactory()的傳回值)的preInstantiateSingletons()方法

第三步:不管是工廠Bean還是普通Bean,最終都是通過getBean方法去擷取執行個體

第四步:調用AbstractBeanFactory的doGetBean()去擷取Bean執行個體,調用createBean()方法

第五步:調用AbstractAutowireCapableBeanFactory的createBean方法,接着調用doCreateBean方法

第六步:調用createBeanInstance()建立Bean執行個體,但是沒有進行屬性設定(依賴注入)

第七步:調用populateBean()方法進行屬性填充,也就是實作依賴注入

第八步:調用initializeBean()進行初始化,并調用BeanPostProcessor後置處理器      

18、談一談Spring Bean的延遲加載的原理?

普通Bean在容器啟動時就初始化了,而被lazy-init=true修飾的Bean則在第一次擷取Bean是觸發初始化。

spring啟動時會把所有的bean資訊(xml和注解)解析為BeanDefinition存儲到HashMap中,然後對每個BeanDefinition進行處理,如果是懶加載則初始化階段不處理。

在bean初始化過程中的preInstantiateSingltons()方法中,有判斷,必須是單例的并且不時懶加載的才會在容器建立時初始化      

19、談一談Spring Ioc的循環依賴問題?

Spring中的循環依賴有構造器的循環依賴和set注入的循環依賴,構造器循環依賴是沒有辦法解決的,隻能抛出BeanCurrentlyInCreationException異常

多執行個體的Bean的循環依賴也是沒有辦法解決的,這裡說的是單執行個體set注入的循環依賴解決

Spring的循環依賴的理論依據是基于Java的引用傳遞,當擷取對象的引用時,對象的屬性是可以延時設定的,但是構造器必須在擷取引用之前。

Spring采用提前暴露一個ObjectFactory對象來完成的,簡單說就是ClassA調用setClassB之前就把ClassA執行個體化的對象通過ObjectFactory提前暴露在Spring容器中了      

SpringMVC面試題

1、什麼是Springmvc?簡單介紹一下你對Springmvc的了解?

Springmvc是一個基于Java的實作了MVC模式的請求驅動類型的輕量級Web架構,通過把Model,VIEW,Controller分離,将web層進行解耦,友善組内開發人員分工合作      

2、Springmvc的工作流程?

1)、工作流程圖

2)、工作流程說明

第一步:使用者發送請求到前端控制器DispatchServlet

第二步:前端控制器收到請求調用處理器映射器HandlerMapping

第三步:處理器映射器根據URL找到具體的處理器Handler,生成處理器對象以及處理器攔截器鍊,并傳回前端控制器

第四步:前端控制器調用處理器擴充卡HandlerAdapter去調用處理器Handler

第五步:處理器擴充卡執行處理器Handler

第六步:處理器Handler執行完成後給處理器擴充卡傳回ModelAndView

第七步:處理器擴充卡将ModelAndView(包含Model,View)傳回給前端控制器

第八步:前端控制器請求視圖解析器ViewResolver進行視圖解析,根據邏輯視圖名解析真正的視圖

第九步:視圖解析器傳回View對象給前端控制器

第十步:前端控制器進行視圖渲染,就是将模型資料填充到request域

第十一步:前端控制器向使用者響應結果      

3、Springmvc的主要元件?

HandlerMapping(處理器映射器)
HandlerMapping的作用就是根據URL擷取響應的處理器,
标注了@RequestMapping的每個方法都可以看做一個Handler,Handler負責處理具體的請求。

HandlerAdapter(處理器擴充卡)
HandlerAdapter是一個擴充卡,SpringMvc中的Handler可以是任意形式,隻要能處理請求即可。但是請求交給Servlet時,Servlet方法結構是doService(HttpServletRequest req,HttpServletResponse resp)形式的,要讓固定的Servlet方法調用Handler進行處理,便是HandlerAdapter的職責

HandlerExceptionResolver(處理器異常解析器)
用于處理Handler産生的異常

ViewResolver(視圖解析器)
用于将String類型的視圖名和Local解析為View類型的視圖,隻有一個resolveViewName()方法

RequestToViewNameTranslator
有些元件沒有設定View,也沒有設定ViewName,該元件從請求中擷取ViewName

LocalResolver
從請求中解析出Local

ThemeResolver
用于解析主題

MultipartResolver
用于上傳請求

FlashMapManager
用于重定向時的參數傳遞      

4、Springmvc如何設定重定向和轉發?

轉發就是在傳回之前面加上forward 重定向就是加上redirect:      

5、如何解決post請求亂碼問題,get請求又如何處理?

post請求亂碼解決,在web.xml中配置CharacterEncondingFilter, Get請求可以修改Tomcat編碼,第二種是對參數進行重新編碼。      

6、Springmvc的異常處理?

@ControllerAdvice+@ExceptionHandler()注解進行處理      

Springboot面試題

1、什麼是Springboot?

SpringBoot用來簡化Spring應用開發,約定大于配置,去繁化簡的輕量級架構

建立獨立的Spring應用程式main方法運作

内嵌Tomcat無需部署war包

簡化maven配置,很多依賴不需要指定版本号

自動配置Spring添加對應starter即可完成自動化配置      

2、Springboot有哪些優缺點?

優點:獨立運作,簡化配置,自動配置,無代碼生成和XML配置(輕量級),應用監控
缺點:太容易上手,但是如果不了解核心技術和流程,一旦遇到問題就會棘手      

3、Spring,Springmvc,Springboot有什麼差別?

Spring最重要的是IOC和AOP技術思想的具體實作,

SpringMVC其實可以說就是封裝了Servlet,讓Web開發更加容易,

Spring和Springmvc均需要大量的配置,SpringBoot自動配置和啟動就是解決它們的問題的      

4、SpringBoot是如何實作自動配置的?

第一步:首先分析@SpringBootApplication注解,由三個核心注解組成@SpringConfiguration,@EnableAutoConfiguration,@ComponentScan

第二步:分析@SpringBootConfiguration發現就是包裝了@Configuration注解,聲明為一個配置類

第三步:分析@EnableAutoConfiguration注解,它由@AutoConfigurationPackage注解和@Import(AutoConfigurationImportSelector.class)組成

第四步:@AutoConfigurationPackage是使用@Import(AutoConfigurationPackages.Registrar.class)導入了該類實作自動掃描包的功能

第五步:進入Registrar.class可以看到它實作了ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法,并傳入了包名,預設是入口程式的包名稱

第六步:回到@EnableAutoConfiguration的第二個注解@Import(AutoConfigurationImportSelector.class),它實作了ImportSelector接口的selectImports方法将符合條件的标注有@Configuration的類注入SpringIoc中

第七步:importSelector會從META-INFO下的spring-autoconfiguration-metadata,properties中加載配置類

第八步:根據中繼資料資訊使用SpringFactoriesLoader在META-INF/spring.factories中加載EnableAutoConfiguration的值,通過反射技術将标注@Configuration的類加載到Ioc容器中,進而實作自動配置

第九步:@ComponentScan可以掃描指定包下面的Bean      

5、Springboot打成jar包和普通的jar有什麼差別?

Springboot打的jar可以直接執行,普通的jar不能直接執行      

6、如何使用Springboot實作異常處理?

@ControllerAdvice + @ExceptionHandler      

7、Springboot中如何解決跨域問題?

重寫WebMvcConfigurer的addCorsMappings方法,或者編寫CorsFilter      

8、Springboot的核心配置檔案有哪幾個?他們的差別是什麼?

application(用于自動配置)和bootstrap(SpringCloud Config,需要在bootstrap中添加連接配接到配置中心的全局配置檔案   一些固定的不能被覆寫的屬性 一些加密解密場景)      

9、Springboot有哪幾種讀取配置的方式?

@Value,@ConfigurationProperties, @PropertySource, @Enviroment      

10、為什麼導入dependency不需要指定版本?

因為spring-boot-start-parent中繼承了spring-boot-dependencies,在這裡面實作了版本号的統一管理      

11、為什麼要自定義starter?

一些公共的元件可以隻要加入jar包,即可使用,友善元件複用      

12、如何自定義starter?

第一步:引入spring-boot-autoconfiguration依賴

第二步:編寫自動配置的配置類,并定義需要加載的Bean

第三步:在resources目錄下建立META-INF/spring.factories檔案

第四步:key為org.springframework.boot.autoconfiguration.EnableAutoConfiguration, value值為自己定義的自動配置類      

13、SpringApplication.run是如何做到啟動SpringBoot項目的呢?

第一步:進入run方法,發現是new SpringApplication,然後調用run方法,也就是先進行初始化,然後再啟動。

第二步:主要是調用setInitializers進行初始化,調用setListeners注冊監聽器,然後給主入口程式類進行指派

第三步:執行run方法啟動容器

第一步:執行getRunListeners()擷取并啟動監聽器

第二步:執行prepareEnviroment()傳入監聽器,準備環境

第三步:執行createApplicationContext()建立Spring容器

第四步:執行prepareContext()做一些前置處理

第五步:執行refreshContext進行容器的重新整理

第六步:執行listeners.started()執行監聽器發送容器啟動完畢的通知

第七步:調用callReturns()方法傳回容器