??????
辛苦牛,掌握主流技術棧,包括前端后端,已經7年時間,曾在稅務機關從事開發(fā)工作,目前在國企任職。希望通過自己的不斷分享,可以幫助各位想或者已經走在這條路上的朋友一定的幫助
前言
??金九銀十馬上就要來啦,各位小伙伴們有計劃跳槽的要開始準備了,博主接下來一段時間會給大家持續(xù)更新面試題目,大家持續(xù)關注一下,感謝??????
今天是Spring IoC的面試題,歡迎指正
之前的面試文章鏈接也給到大家
金九銀十面試題之Mysql
金九銀十面試題之設計模式
金九銀十面試題之數(shù)據(jù)結構和算法
金九銀十面試題之Mybatis
金九銀十面試題之《Spring Data JPA、Spring MVC、AOP》
內容
?? Q1:IoC 是什么?
IoC 即控制反轉,簡單來說就是把原來代碼里需要實現(xiàn)的對象創(chuàng)建、依賴反轉給容器來幫忙實現(xiàn),需要創(chuàng) 建一個容器并且需要一種描述讓容器知道要創(chuàng)建的對象間的關系,在 Spring 中管理對象及其依賴關系 是通過 Spring 的 IoC 容器實現(xiàn)的。
IoC 的實現(xiàn)方式有依賴注入和依賴查找,由于依賴查找使用的很少,因此 IoC 也叫做依賴注入。依賴注 入指對象被動地接受依賴類而不用自己主動去找,對象不是從容器中查找它依賴的類,而是在容器實例 化對象時主動將它依賴的類注入給它。假設一個 Car 類需要一個 Engine 的對象,那么一般需要需要手 動 new 一個 Engine,利用 IoC 就只需要定義一個私有的 Engine 類型的成員變量,容器會在運行時自 動創(chuàng)建一個 Engine 的實例對象并將引用自動注入給成員變量。
?? Q2:IoC 容器初始化過程?
基于 XML 的容器初始化
當創(chuàng)建一個 ClassPathXmlApplicationContext 時,構造方法做了兩件事:1 調用父容器的構造方法為 容器設置好Bean資源加載器。2調用父類的setConfigLocations 方法設置Bean配置信息的定位路徑。
ClassPathXmlApplicationContext 通過調用父類 AbstractApplicationContext 的 refresh 方法啟動整個 IoC 容器對 Bean 定義的載入過程,refresh 是一個模板方法,規(guī)定了 IoC 容器的啟動流程。在 創(chuàng)建 IoC 容器前如果已有容器存在,需要把已有的容器銷毀,保證在 refresh 方法后使用的是新創(chuàng)建 的 IoC 容器。
容器創(chuàng)建后通過 loadBeanDefinitions 方法加載 Bean 配置資源,該方法做兩件事:1 調用資源加載器的方法獲取要加載的資源。2 真正執(zhí)行加載功能,由子類 XmlBeanDefinitionReader 實現(xiàn)。加載 資源時首先解析配置文件路徑,讀取配置文件的內容,然后通過 XML 解析器將 Bean 配置信息轉換成文檔對象,之后按照 Spring Bean 的定義規(guī)則對文檔對象進行解析。
Spring IoC 容器中注冊解析的 Bean 信息存放在一個 HashMap 集合中,key 是字符串,值是 BeanDefinition,注冊過程中需要使用 synchronized 保證線程安全。當配置信息中配置的 Bean 被解 析且被注冊到 IoC 容器中后,初始化就算真正完成了,Bean 定義信息已經可以使用且可被檢索。 Spring IoC 容器的作用就是對這些注冊的 Bean 定義信息進行處理和維護,注冊的 Bean 定義信息是控 制反轉和依賴注入的基礎。
基于注解的容器初始化
分為兩種:1 直接將注解 Bean 注冊到容器中,可以在初始化容器時注冊,也可以在容器創(chuàng)建之后手動 注冊,然后刷新容器使其對注冊的注解 Bean 進行處理。2 通過掃描指定的包及其子包的所有類處理, 在初始化注解容器時指定要自動掃描的路徑。
?? Q3:依賴注入的實現(xiàn)方法有哪些?
構造方法注入: IoC Service Provider 會檢查被注入對象的構造方法,取得它所需要的依賴對象列表, 進而為其注入相應的對象。這種方法的優(yōu)點是在對象構造完成后就處于就緒狀態(tài),可以?上使用。缺點 是當依賴對象較多時,構造方法的參數(shù)列表會比較?,構造方法無法被繼承,無法設置默認值。對于非 必需的依賴處理可能需要引入多個構造方法,參數(shù)數(shù)量的變動可能會造成維護的困難。
setter 方法注入: 當前對象只需要為其依賴對象對應的屬性添加 setter 方法,就可以通過 setter 方法 將依賴對象注入到被依賴對象中。setter 方法注入在描述性上要比構造方法注入強,并且可以被繼承, 允許設置默認值。缺點是無法在對象構造完成后?上進入就緒狀態(tài)。
接口注入: 必須實現(xiàn)某個接口,接口提供方法來為其注入依賴對象。使用少,因為它強制要求被注入對象 實現(xiàn)不必要接口,侵入性強。
?? Q4:依賴注入的相關注解?
@Autowired :自動按類型注入,如果有多個匹配則按照指定 Bean 的 id 查找,查找不到會報錯。
@Qualifier :在自動按照類型注入的基礎上再按照 Bean 的 id 注入,給變量注入時必須搭配 @Autowired ,給方法注入時可單獨使用。
@Resource :直接按照 Bean 的 id 注入,只能注入 Bean 類型。
@Value :用于注入基本數(shù)據(jù)類型和 String 類型。
?? Q5:依賴注入的過程?
getBean 方法獲取 Bean實例,該方調用doGetBean , doGetBean 真正實現(xiàn)從 IoC 容器獲取
Bean 的功能,也是觸發(fā)依賴注入的地方。
具體創(chuàng)建 Bean 對象的過程由 ObjectFactory 的 createBean 完成,該方法主要通過
createBeanInstance 方法生成Bean包含的Java對象實例和populateBean 方法對Bean屬性的 依賴注入進行處理。
在 populateBean 方法中,注入過程主要分為兩種情況:
- 屬性值類型不需要強制轉換時,不需要解 析屬性值,直接進行依賴注入。
- 屬性值類型需要強制轉換時,首先解析屬性值,然后對解析后的屬性值 進行依賴注入。依賴注入的過程就是將 Bean 對象實例設置到它所依賴的 Bean 對象屬性上,真正的依賴注入是通過 setPropertyValues 方法實現(xiàn)的,該方法使用了委派模式。
BeanWrapperImpl 類負責對完成初始化的 Bean 對象進行依賴注入,對于非集合類型屬性,使用 JDK 反射,通過屬性的 setter 方法為屬性設置注入后的值。對于集合類型的屬性,將屬性值解析為目標類型 的集合后直接賦值給屬性。
當容器對 Bean 的定位、載入、解析和依賴注入全部完成后就不再需要手動創(chuàng)建對象,IoC 容器會自動 為我們創(chuàng)建對象并且注入依賴。
?? Q6:Bean 的生命周期?
在 IoC 容器的初始化過程中會對 Bean 定義完成資源定位,加載讀取配置并解析,最后將解析的 Bean 信息放在一個 HashMap 集合中。當 IoC 容器初始化完成后,會進行對 Bean 實例的創(chuàng)建和依賴注入過 程,注入對象依賴的各種屬性值,在初始化時可以指定自定義的初始化方法。經過這一系列初始化操作 后 Bean 達到可用狀態(tài),接下來就可以使用 Bean 了,當使用完成后會調用 destroy 方法進行銷毀,此 時也可以指定自定義的銷毀方法,最終 Bean 被銷毀且從容器中移除。
XML 方式通過配置 bean 標簽中的 init-Method 和 destory-Method 指定自定義初始化和銷毀方法。 注解方式通過 @PreConstruct 和 @PostConstruct 注解指定自定義初始化和銷毀方法。
?? Q7:Bean 的作用范圍?
通過 scope 屬性指定 bean 的作用范圍,包括:
- singleton:單例模式,是默認作用域,不管收到多少 Bean 請求每個容器中只有一個唯一的 Bean 實 例。
- prototype:原型模式,和 singleton 相反,每次 Bean 請求都會創(chuàng)建一個新的實例。
- request:每次 HTTP 請求都會創(chuàng)建一個新的 Bean 并把它放到 request 域中,在請求完成后 Bean
會失效并被垃圾收集器回收。 - session:和 request 類似,確保每個 session 中有一個 Bean 實例,session 過期后 bean 會隨之失 效。
- global session:當應用部署在 Portlet 容器時,如果想讓所有 Portlet 共用全局存儲變量,那么該變 量需要存儲在 global session 中。
?? Q8:如何通過 XML 方式創(chuàng)建 Bean?
默認無參構造方法,只需要指明 bean 標簽中的 id 和 class 屬性,如果沒有無參構造方法會報錯。
靜態(tài)工廠方法,通過 bean 標簽中的 class 屬性指明靜態(tài)工廠,factory-method 屬性指明靜態(tài)工廠方法。
實例工廠方法,通過 bean 標簽中的 factory-bean 屬性指明實例工廠,factory-method 屬性指明實例 工廠方法。
?? Q9:如何通過注解創(chuàng)建 Bean?
@Component 把當前類對象存入 Spring 容器中,相當于在 xml 中配置一個 bean 標簽。value 屬性指
定 bean 的 id,默認使用當前類的首字母小寫的類名。
@Controller , @Service , @Repository 三個注解都是 @Component 的衍生注解,作用及屬性都 是一模一樣的。只是提供了更加明確語義, @Controller 用于表現(xiàn)層, @Service 用于業(yè)務層, @Repository 用于持久層。如果注解中有且只有一個 value 屬性要賦值時可以省略 value。
如果想將第三方的類變成組件又沒有源代碼,也就沒辦法使用@Component 進行自動配置,這種時候 就要使用 @Bean 注解。被 @Bean 注解的方法返回值是一個對象,將會實例化,配置和初始化一個新
對象并返回,這個對象由 Spring 的 IoC 容器管理。name 屬性用于給當前 @Bean 注解方法創(chuàng)建的對象 指定一個名稱,即 bean 的 id。當使用注解配置方法時,如果方法有參數(shù),Spring 會去容器查找是否有 可用 bean對象,查找方式和 @Autowired 一樣。
?? Q10:如何通過注解配置文件?
@Configuration 用于指定當前類是一個 spring 配置類,當創(chuàng)建容器時會從該類上加載注解,value
屬性用于指定配置類的字節(jié)碼。
@ComponentScan 用于指定 Spring 在初始化容器時要掃描的包。basePackages 屬性用于指定要掃描 的包。
@PropertySource 用于加載 .properties 文件中的配置。value 屬性用于指定文件位置,如果是在 類路徑下需要加上 classpath。
@Import 用于導入其他配置類,在引入其他配置類時可以不用再寫 @Configuration 注解。有 @Import 的是父配置類,引入的是子配置類。value 屬性用于指定其他配置類的字節(jié)碼。
?? Q11:BeanFactory、FactoryBean 和 ApplicationContext 的區(qū)別?
BeanFactory 是一個 Bean 工廠,使用簡單工廠模式,是 Spring IoC 容器頂級接口,可以理解為含有 Bean 集合的工廠類,作用是管理 Bean,包括實例化、定位、配置對象及建立這些對象間的依賴。 BeanFactory 實例化后并不會自動實例化 Bean,只有當 Bean 被使用時才實例化與裝配依賴關系,屬 于延遲加載,適合多例模式。
FactoryBean 是一個工廠 Bean,使用了工廠方法模式,作用是生產其他 Bean 實例,可以通過實現(xiàn)該 接口,提供一個工廠方法來自定義實例化 Bean 的邏輯。FactoryBean 接口由 BeanFactory 中配置的對 象實現(xiàn),這些對象本身就是用于創(chuàng)建對象的工廠,如果一個 Bean 實現(xiàn)了這個接口,那么它就是創(chuàng)建對 象的工廠 Bean,而不是 Bean 實例本身。
ApplicationConext 是 BeanFactory 的子接口,擴展了 BeanFactory 的功能,提供了支持國際化的文本 消息,統(tǒng)一的資源文件讀取方式,事件傳播以及應用層的特別配置等。容器會在初始化時對配置的 Bean 進行預實例化,Bean 的依賴注入在容器初始化時就已經完成,屬于立即加載,適合單例模式,一 般推薦使用。文章來源:http://www.zghlxwxcb.cn/news/detail-634825.html
寫在最后
希望博主收集的內容能幫到大家,祝大家能找到一個好的工作,過好的生活,如有錯誤歡迎指正。 ??????文章來源地址http://www.zghlxwxcb.cn/news/detail-634825.html
到了這里,關于金九銀十面試題之《Spring IOC》的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!