面試問你爲何要用Spring怎麼答?

相信每一個讀者在工做中,學習中都瞭解Spring怎麼使用,對於一個初級的開發工程師來講,僅僅瞭解怎麼使用,可以很快的經過Spring來完成任務,這應該是足夠了,可是呢,若是你還想向更高的級別去前進,系統的學習,掌握它的底層原理是必不可少的。java

每一個人在面試的時候,Spring應該都是逃不過的關卡,可以熟練的使用,這並不難,知道它的底層原理纔是高出別人一步的地方。這篇文章就說簡單說下Spring的一些知識,但願能在面試的路上幫助到大家。面試

Spring是個開源框架,它被建立出來的初衷就是解決企業級應用開發的複雜性。Spring不只僅侷限於服務端開發,任何的java應用都能借助於Spring變得更加簡單,可測試性更強,鬆耦合性更好。spring

爲了下降Java開發的複雜性,Spring採起了一下4種關鍵策略:編程

  • 基於POJO的輕量級和最小侵入性編程;安全

  • 經過依賴注入和麪向接口實現鬆耦合;bash

  • 基於切面和慣例進行聲明式編程;app

  • 經過切面和模板減小樣板式代碼。框架

    幾乎Spring所作的任何事情,都是圍繞着以上四種策略來實現的,其核心就是:簡化java開發。
    複製代碼

一、輕量級POJO模塊化

在平常的開發過程當中,可能大部分人都感覺到了,不少框架都會強迫應用繼承他們的類或者是實現他們的接口,這樣就會致使程序和框架綁死,說到這,咱們的如今所用的框架就是這樣,各個模塊,包括DAO,Service,都會強制性的繼承框架的中的類,應用程序和框架綁定的死死的。Spring竭力的避免由於自身的API來搞亂你的應用代碼,Spring也不會強迫你實現他的接口或者是繼承它的類,最嚴重的也就是一個雷會使用Spring註解。Spring的非侵入式編程意味着這個類在Spring應用和非Spring應用中發揮着一樣的做用。函數

二、依賴注入

任何一個有實際意義的應用,確定是會有多個類組成,在沒有Spring的時候,每一個對象負責管理着與本身相互協做的對象的引用,這樣會致使高耦合和難以測試的代碼。

public class Train implements Transport{
   private Water water;
   public Train() {
       water = new Water();
  }
   public void catchGoods(){
       water.waterSomthing();
  }
}
複製代碼

能夠看到上面的代碼,Train在本身的構造函數中本身建立了 Water對象,這樣就形成了這兩個對象的緊耦合,這個火車能夠運水來澆灌農田,可是若是讓這個火車來運煤供暖,可能就不太符合了。

而在單元測試的時候,咱們要確保catchGoods方法執行的時候,waterSomthing也可以執行,若是這樣來作,那就執行不了單元測試了。

耦合是具備兩面性的,一方面緊密的耦合的代碼,難以測試,難以服用,難以理解,修改了一處就可能會引發別的bug(記得剛去公司的時候,講開發規範,一個接口儘可能的只作一件事情,千萬不要一個接口同時爲多個地方提供服務),另外一方面呢徹底沒有耦合的代碼也什麼都幹不了。

有了Spring以後,對象的依賴關係由負責協調各對象的第三方組件來完成,對象無需自行建立,依賴注入會將所依賴的關係自動交給目標對象,而不是讓對象本身去獲取。

public class Train implements Transport{
   private Water water;
   public Train(Water water) {
       this.water = water;
  }
   public void catchGoods(){
       water.waterSomthing();
  }
}
複製代碼

上面在咱們的改動以後,再也不由Train自行建立,而是當成一個構造器參數傳進來,這也是依賴注入的一種方式:構造器注入。這也就實現了鬆耦合。

建立應用組件之間協做的行爲一般稱爲裝配,Spring有着多種裝配bean的方式,XML就是一種經常使用的方式。

<?xml version="1.0" encoding="UTF-8"?>
<!--DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd" -->
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="train" class="com.kr.caption.spring.Train">
       <constructor-arg ref="water"/>
   </bean>
   <bean id="water" class="com.kr.caption.spring.Water"/>
</beans>
複製代碼

在上面的xml文件中,兩個對象被聲明爲了Spring中的bean,在Train中,在構造時傳入了對Water的引用,做爲構造器參數。

@Configuration
public class TrainConfig {
   @Bean
   public Transport train(){
       return new Train(water());
  }
   @Bean
   public Water water(){
       return new Water();
  }
}
複製代碼

上面的是基於java的配置,這兩種配置都是同樣的效果。

Spring經過應用的上下文,來裝載bean的定義,並把他們組裝起來,Spring應用上下文全權負責對象的建立和組裝,Spring有多種上下文的實現,它們之間主要的區別僅僅在於如何加載配置。

public class application {
   public static void main(String[] args) {
       ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:application_example.xml");
       Train bean = context.getBean(Train.class);
       bean.catchGoods();
  }
}
複製代碼

這裏的main方法基於application_example.xml建立了一個Spring應用上下文,隨後就能獲得一個實例對象,直接調用方法便可。

三、面向切面編程

系統由不一樣的組件組成,而這些組件除了實現自身的核心功能外,還承擔着其餘的一些職責。好比日誌、事務管理和安全這些一般會貫穿着整個項目中的各個組件。若是沒有系統性的處理這部分,那麼你的代碼會含有大量的重複代碼。若是你把這些單獨抽象爲一個模塊,其餘模塊只是調用它的方法,方法的調用仍是會出現各個模塊。

AOP會使這些服務模塊化,以聲明的方式應用到它們須要影響的模塊去,這樣其餘的模塊就會只關注它們自身的業務,徹底不須要了解這些服務的相關邏輯和代碼。

看到上面的圖片,咱們能夠把切面想象爲覆蓋在不少組件上的一個外殼,藉助AOP可使那些功能層去包裹核心業務層,這些功能層以聲明的方式靈活的應用到系統中,其餘的業務應用根本不知道它的存在。

寫在最後

這裏沒有太多的花言巧語,若是本文對你有所幫助,但願點擊下面的二維碼關注一波,或者是朋友圈分享一下,點個好看也是棒棒的。

這樣的分享我會一直持續,你的關注、轉發和好看是對我最大的支持,感謝。

相關文章
相關標籤/搜索