Java開發工程師最新面試題庫系列——Spring部分(附答案)

Spring
  1. Spring框架是什麼?

    答:Spring是輕量級的面向切面和控制反轉的框架。初代版本為2002年發佈的interface21,Spring框架是為了解決企業級應用開發的複雜性的出現的,它可以幫助開發人員管理對象之間的關係。能實現模塊與模塊之間、類與類之間的解耦合,Spring是一個大雜燴,它集成其他許多框架,使其他框架能與spring結合搭配使用

  2. Spring常用的註解有哪些?

    答:

    1、@Controller

    在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務bai處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在SpringMVC 中提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實現特定的接口,只需使用@Controller 標記一個類是Controller ,然後使用@RequestMapping 和@RequestParam 等一些註解用以定義URL 請求和Controller 方法之間的映射,這樣的Controller 就能被外界訪問到。此外Controller 不會直接依賴於HttpServletRequest 和HttpServletResponse 等HttpServlet 對象,它們可以通過Controller 的方法參數靈活的獲取到。
    @Controller 用於標記在一個類上,使用它標記的類就是一個SpringMVC Controller 對象。分發處理器將會掃描使用了該註解的類的方法,並檢測該方法是否使用了@RequestMapping 註解。@Controller 只是定義了一個控制器類,而使用@RequestMapping 註解的方法才是真正處理請求的處理器。單單使用@Controller 標記在一個類上還不能真正意義上的說它就是SpringMVC 的一個控制器類,因為這個時候Spring 還不認識它。那麼要如何做Spring 才能認識它呢?這個時候就需要我們把這個控制器類交給Spring 來管理。有兩種方式:
    (1)在SpringMVC 的配置文件中定義MyController 的bean 對象。
    (2)在SpringMVC 的配置文件中告訴Spring 該到哪裡去找標記為@Controller 的Controller 控制器。

    2、@RequestMapping

    RequestMapping是一個用來處理請求地址映射的註解,可用於類或方法上。用於類上,表示類中的所有響應請求的方法都是以該地址作為父路徑。
    3、@Resource和@Autowired
    @Resource和@Autowired都是做bean的注入時使用,其實@Resource並不是Spring的註解,它的包是javax.annotation.Resource,需要導入,但是Spring支持該註解的注入。

    4、@ModelAttribute和 @SessionAttributes

    代表的是:該Controller的所有方法在調用前,先執行此@ModelAttribute方法,可用於註解和方法參數中,可以把這個@ModelAttribute特性,應用在BaseController當中,所有的Controller繼承BaseController,即可實現在調用Controller時,先執行@ModelAttribute方法。
    @SessionAttributes即將值放到session作用域中,寫在class上面。
    具體示例參見下面:使用 @ModelAttribute 和 @SessionAttributes 傳遞和保存數據

    5、@PathVariable

    用於將請求URL中的模板變量映射到功能處理方法的參數上,即取出uri模板中的變量作為參數。

    6、@requestParam

    @requestParam主要用於在SpringMVC後台控制層獲取參數,類似一種是request.getParameter(“name”),它有三個常用參數:defaultValue = “0”, required = false, value = “isApp”;defaultValue 表示設置默認值,required 銅過boolean設置是否是必須要傳入的參數,value 值表示接受的傳入的參數類型。

    7、@ResponseBody

    作用: 該註解用於將Controller的方法返回的對象,通過適當的HttpMessageConverter轉換為指定格式後,寫入到Response對象的body數據區。
    使用時機:返回的數據不是html標籤的頁面,而是其他某種格式的數據時(如json、xml等)使用;

    8、@Component

    相當於通用的註解,當不知道一些類歸到哪個層時使用,如果有WEB開發架構中固定的層則使用更加語義化的註解@Repository註解於DAO層、@Service註解於Service層、@Controller 註解於Controller層

  3. Spring框架有哪些好處?

    答:Spring能有效地組織你的中間層對象,為模塊之間降低耦合。還包括輕量級,面向切面,控制反轉,都是Spring的好處

  4. Spring由哪些主要模塊組成?

    答:

    img

  5. Spring IOC容器是什麼?

    答:IOC容器意味着將對象交給IOC容器接管,由這樣一個容器幫助我們管理對象,而不是傳統的由開發人員管理對象。IOC可以幫助我們注入屬性給對象,需要的時候給我們。

  6. Spring IOC有哪些好處?

    答:降低模塊與模塊之間的耦合,降低類與類之間的耦合。讓開發人員不再做重複的對象創建賦值等繁瑣的操作,而是需要用到時由IOC容器創建好自己傳遞過來

  7. BeanFactory和ApplicationContext有什麼區別?

    答:

    BeanFactory:

    是Spring裏面最低層的接口,提供了最簡單的容器的功能,只提供了實例化對象和拿對象的功能;

    ApplicationContext:

    應用上下文,繼承BeanFactory接口,它是Spring的一各更高級的容器,提供了更多的有用的功能;

    1. 國際化(MessageSource)

    2. 訪問資源,如URL和文件(ResourceLoader)

    3. 載入多個(有繼承關係)上下文 ,使得每一個上下文都專註於一個特定的層次,比如應用的web層

    4. 消息發送、響應機制(ApplicationEventPublisher)

    5. AOP(攔截器)

    兩者裝載bean的區別

    BeanFactory:

    BeanFactory在啟動的時候不會去實例化Bean,中有從容器中拿Bean的時候才會去實例化;

    ApplicationContext:

    ApplicationContext在啟動的時候就把所有的Bean全部實例化了。它還可以為Bean配置lazy-init=true來讓Bean延遲實例化;

    我們該用BeanFactory還是ApplicationContext

    延遲實例化的優點:(BeanFactory

    應用啟動的時候佔用資源很少;對資源要求較高的應用,比較有優勢;

    不延遲實例化的優點: (ApplicationContext

    1. 所有的Bean在啟動的時候都加載,系統運行的速度快;

    2. 在啟動的時候所有的Bean都加載了,我們就能在系統啟動的時候,儘早的發現系統中的配置問題

    3. 建議web應用,在啟動的時候就把所有的Bean都加載了。(把費時的操作放到系統啟動中完成)

  8. Spring的依賴注入是什麼?

    答:主動尋找依賴屬性,通過set方法或者構造函數等方式注入到對象內部。

  9. Spring的依賴注入有幾種方式?

    答:構造器注入,setter注入,接口注入

    依賴類必須要實現指定的接口,然後實現該接口中的一個函數,該函數就是用於依賴注入。該函數的參
    數就是要注入的對象。
    優點:
    接口注入中,接口的名字、函數的名字都不重要,只要保證函數的參數是要注入的對象類型即可。
    缺點:
    侵入行太強,不建議使用。

  10. Spring Bean支持哪幾種作用域?

    答:singlet單例,prototype多例,request HTTP請求,session會話,session-global全局會話

  11. Spring Bean生命周期是怎樣的?

    答:

    imgimg

    Spring Bean生命周期

  12. Spring Bean為什麼默認是單例的?

    答:

    1、如果是多例會參數較大的性能消耗,體現在創建對象,回收對象的過程。

    2、單例的話自始至終都只有一個對象,Spring創建好後就放入了緩存,需要使用時可以快速獲取。

  13. Spring Bean是線程安全的嗎?

    答:當Bean的作用域範圍是singlet時線程是不安全的,因為所有的線程都會共享這一個實例,必然存在資源競爭,為prototype時線程安全。

  14. Spring怎麼注入Java集合類型?

    答:使用標籤或者標籤進行進入

    <bean name="list" class="cn.itcast.injection.CollectionBean">
    		<!-- List 注入 -->
            <property name="list">
                <list>
                    <value>tom</value>
                    <value>tom</value>
                    <ref bean="user3"/>
                </list>
            </property>
    </bean>
    
  15. Spring自動裝配是指什麼?

    答:自動裝配就是讓應用程序上下文為你找出依賴項的過程。說的通俗一點,就是Spring會在上下文中自動查找,並自動給bean裝配與其關聯的屬性!

  16. Spring自動裝配有哪些方式?

    答:大體上有兩種方式,xml方式和註解方式。xml方式在bean標籤中加入屬性autowire=””,值可以選擇byName、byType、constructor,需要在類中為需要注入的屬性提供setter方法。註解方式@Autowire,先根據byType尋找bean,如果找到數量大於1再根據byName尋找、@Resource根據byType注入、@Qualifier(“beanName”)指定beanName注入

  17. Spring自動裝配有什麼局限性?

    答:

    • 重寫: 你仍需用 配置來定義依賴,意味着總要重寫自動裝配。

    • 基本數據類型:你不能自動裝配簡單的屬性,如基本數據類型,String字符串,和類。

    • 模糊特性:自動裝配不如顯式裝配精確,如果有可能,建議使用顯式裝配。

  18. Spring AOP是什麼?

    答:將對業務操作重複的操作封裝為模塊,通過動態代理的方式注入到方法中。

  19. Spring AOP有什麼作用?

    答:

    Authentication 權限

    Caching 緩存

    Context passing 內容傳遞

    Error handling 錯誤處理

    Lazy loading 懶加載

    Debugging  調試

    logging, tracing, profiling and monitoring 記錄跟蹤 優化 校準

    Performance optimization 性能優化

    Persistence  持久化

    Resource pooling 資源池

    Synchronization 同步

    Transactions 事務

  20. Spring AOP有哪些實現方式?

    答:JDK動態代理和cglib,spring根據被代理類的類型採用適合的方式進行實現啊,如果是接口就採用JDK動態代理,如果是類就採用cglib方式。

  21. Spring AOP和AspectJ AOP有什麼區別?

    Spring AOP AspectJ
    在純 Java 中實現 使用 Java 編程語言的擴展實現
    不需要單獨的編譯過程 除非設置 LTW,否則需要 AspectJ 編譯器 (ajc)
    只能使用運行時織入 運行時織入不可用。支持編譯時、編譯後和加載時織入
    功能不強-僅支持方法級編織 更強大 – 可以編織字段、方法、構造函數、靜態初始值設定項、最終類/方法等…。
    只能在由 Spring 容器管理的 bean 上實現 可以在所有域對象上實現
    僅支持方法執行切入點 支持所有切入點
    代理是由目標對象創建的, 並且切面應用在這些代理上 在執行應用程序之前 (在運行時) 前, 各方面直接在代碼中進行織入
    比 AspectJ 慢多了 更好的性能
    易於學習和應用 相對於 Spring AOP 來說更複雜
  22. Spring支持哪些事務管理類型?

    答:

    • 編程式事務管理,在代碼中顯式調用開啟事務、提交事務、回滾事務的相關方法
    • 聲明式事務管理,底層是建立在 AOP 的基礎之上。其本質是對方法前後進行攔截,然後在目標方法開始之前創建或者加入一個事務,在執行完目標方法之後根據執行情況提交或者回滾事務。
  23. Spring框架用了哪些設計模式?

    答:

    1、代理模式:在AOP和remoting中被用的比較多

    2、單例模式:在spring配置文件中定義的bean默認為單例模式

    3、模板方法模式:解決代碼重複問題

    父類定義骨架(共同方法的實現,調用哪些方法及順序),某些特定方法由子類實現(父類是空方法,子類繼承後再重寫)

    4、前端控制器模式:spring提供了DispatcherServlet來對請求進行分發

    5、依賴注入模式:貫穿於BeanFactory和ApplicationContext接口的核心理念

    6、工廠模式:

    (1)簡單工廠:

    實現方式:BeanFactory根據傳入一個唯一的標識來獲得bean對象,由工廠類根據傳入的參數動態決定應該創建哪一個產品類

    實現原理:

    bean容器的啟動階段:讀取bean的xml配置文件,將bean元素分別轉換成一個BeanDefinition對象。然後通過BeanDefinitionRegistry將這些bean註冊到beanFactory中。

    容器中bean的實例化階段:主要通過反射或者CGLIB對bean進行實例化

    (2)工廠方法:

    實現方式:FactoryBean接口

    實現原理:實現了FactoryBean接口的bean是一類叫做factory的bean,特點是spring會在使用getBean()調用獲得該bean時,自動調用該bean的getObject()方法。返回的是這個bean.getObject()方法的返回值。

    典型例子:spring與mybatis的結合:

    //最終返回的是SqlSessionFactoryBean.getObject()的返回值

    7、適配器模式

    實現方式:springmvc中的適配器HandlerAdapter

    實現過程:dispatcherServlet根據HandlerMapping返回的handler,向HandlerAdapter發起請求,處理handler。HandlerAdapter根據規則找到對應的Handler並讓其執行,執行完畢後Handler會向HandlerAdapter返回一個ModelAndView,最後由HandlerAdapter向dispatcherServlet返回一個ModelAndView

    8、裝飾器模式:

    實現方式:類名中包含Wrapper,或者是Decorator,就是裝飾器模式

    實質:動態地給一個對象添加一些額外的職責,比生成子類更靈活

    9、觀察者模式

    實現方式:spring的事件驅動模型使用的是觀察者模式,常用的地方就是listener的實現

    具體實現:事件機制的實現包括事件源、事件、事件監聽器:

    ApplicationEvent抽象類【事件】

    ApplicationListener接口【事件監聽器】

    ApplicationContext接口【事件源】

    10、策略模式

    實現方式:spring框架的資源訪問Resource接口,是具體資源訪問策略的抽象,也是所有資源訪問類所實現的接口

  24. Spring MVC框架有什麼用?

    答:SpringMvc是輕量級、松耦合的MVC框架,提供模型-視圖-控制器層的不同支持。

  25. Spring MVC DispatcherServlet的工作流程?

    答:

    1. Tomcat 啟動,對 DispatcherServlet 進行實例化,然後調用它的 init() 方法進行初始化,在這個初始化過程中完成了:

    2. 對 web.xml 中初始化參數的加載;建立 WebApplicationContext (SpringMVC的IOC容器);進行組件的初始化;

    3. 客戶端發出請求,由 Tomcat 接收到這個請求,如果匹配 DispatcherServlet 在 web.xml 中配置的映射路徑,Tomcat 就將請求轉交給 DispatcherServlet 處理;

    4. DispatcherServlet 從容器中取出所有 HandlerMapping 實例(每個實例對應一個 HandlerMapping 接口的實現類)並遍歷,每個 HandlerMapping 會根據請求信息,通過自己實現類中的方式去找到處理該請求的 Handler (執行程序,如Controller中的方法),並且將這個 Handler 與一堆 HandlerInterceptor (攔截器) 封裝成一個 HandlerExecutionChain 對象,一旦有一個 HandlerMapping 可以找到 Handler 則退出循環;(詳情可以看[ Java]SpringMVC工作原理之二:HandlerMapping和HandlerAdpater 這篇文章)

    5. DispatcherServlet 取出 HandlerAdapter 組件,根據已經找到的 Handler,再從所有 HandlerAdapter 中找到可以處理該 Handler 的 HandlerAdapter 對象;

    6. 執行 HandlerExecutionChain 中所有攔截器的 preHandler() 方法,然後再利用 HandlerAdapter 執行 Handler ,執行完成得到 ModelAndView,再依次調用攔截器的 postHandler() 方法;

    7. 利用 ViewResolver 將 ModelAndView 或是 Exception(可解析成 ModelAndView)解析成 View,然後 View 會調用 render() 方法再根據 ModelAndView 中的數據渲染出頁面;

    8. 最後再依次調用攔截器的 afterCompletion() 方法,這一次請求就結束了。