Java筆試面試-Spring 核心

  Spring Framework 簡稱 Spring,是 Java 開發中最常用的框架,地位僅次於 Java API,就連近幾年比較流行的微服務框架 SpringBoot,也是基於 Spring 實現的,SpringBoot 的誕生是爲了讓開發者更方便地使用 Spring,因此 Spring 在 Java 體系中的地位可謂首屈一指。

Spring 介紹

  Spring 是一個開源框架,爲了解決企業應用程序開發複雜性而創建的,Spring 的概念誕生於 2002 年,於 2003 年正式發佈第一個版本 Spring Framework 0.9。

Spring 1.x
  此版本主要是爲了解決企業應用程序開發複雜性而創建的,當時 J2EE 應用的經典架構是分層架構:表現層、業務層、持久層,最流行的組合就是 SSH(Struts、Spring、Hibernate)。
  Spring 1.x 僅支持基於 XML 的配置,確保用戶代碼不依賴 Spring,它主要包含了以下功能模塊:aop、beans、ejb、jdbc、jndi、orm、transation、validation、web 等。

Spring 2.x
  Spring 2.x 的改動並不是很大,主要是在 Spring 1.x 的基礎上增加了幾個新模塊,如 ehcache、jms、jmx、scripting、stereotype 等。

Spring 3.x
  Spring 3.x 開始不止支持 XML 的配置,還擴展了基於 Java 類的配置,還增加了 Expression、Instructment、Tomcat、oxm 等組件,同時將原來的 Web 細分爲:Portlet、Servlet。

Spring 4.x
  Spring 4.x 擴充了 Groovy、Messaging、WebMvc、Tiles2、WebSocket 等功能組件,同時 Spring 還適配了 Java 版本,全面支持 Java 8.0、Lambda 表達式等。隨着 RESTful 架構風格被越來越多的用戶所採用,Spring 4.x 也提供了 RestController 等註解新特性。

Spring 5.x
  Spring 5.x 緊跟 Java 相關技術的更新迭代,不斷適配 Java 的新版本,同時不斷重構優化自身核心框架代碼,支持函數式、響應式編程模型等。

Spring 核心

Spring 核心包括以下三個方面:

  • 控制反轉(Ioc)
  • 依賴注入(DI)
  • 面向切面編程(AOP)

控制反轉(IoC)
  控制反轉(Inversion of Control,IoC),顧名思義所謂的控制反轉就是把創建對象的權利交給框架去控制,而不需要人爲地去創建,這樣就實現了可插拔式的接口編程,有效地降低代碼的耦合度,降低了擴展和維護的成本
比如,你去某地旅遊不再用自己親自爲訂購 A 酒店還是 B 酒店而發愁了,只需要把住店的需求告訴給某個託管平臺,這個託管平臺就會幫你訂購一個既便宜又舒適的酒店,而這個幫你訂購酒店的行爲就可以稱之爲控制反轉。

依賴注入(DI)
  依賴注入(Dependency Injection,DI),是組件之間依賴關係由容器在運行期決定,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並非爲軟件系統帶來更多功能,而是爲了提升組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。通過依賴注入機制,只需要通過簡單的配置,而無需任何代碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。

IoC 和 DI 的關係
  IoC 是 Spring 中一個極爲重要的概念,而 DI 則是實現 IoC 的方法和手段。

依賴注入的常見實現方式

  • setter 注入
  • 構造方法注入
  • 註解注入

1.setter 注入

Java 代碼:

public class UserController {
    // 注入 UserService 對象
    private UserService userService;
    public void setUserService(UserService userService){
        this.userService = userService;
    }
}

XML 配置:

<bean name="userController" class="com.learning.controller.UserController">  
    <!-- 依賴注入 -->  
    <property name="userService" ref="userService"></property>  
</bean>  
<bean name="userService" class="com.learning.dao.impl.UserServiceImpl"></bean>

Bean 標籤的常用屬性說明:

  • id:爲實例化對象起名稱,根據 id 值可以得到我們配置的實例化對象,id 屬性的名稱原則上可以任意命名,但是能包含任何特殊符號;
  • class:創建對象所在類的全路徑;
  • name:功能和 id 屬性一樣,但是現在一般不用;與 id 的區別在於:name 屬性值裏可以包含特殊符號,但是 id 不可以;
  • scope:一般最常用的有兩個值: Singleton:單例模式,整個應用程序,只創建 bean 的一個實例;Prototype:原型模式,每次注入都會創建一個新的 bean 實例,Spring 默認的是單例模式。

2.構造方法注入

Java 代碼:

public class UserController {
    private UserService userService;
    public UserController(UserService userService){
        this.userService = userService;
    }
}

XML 配置:

<bean name="userController" class="com.learning.controller.UserController">  
    <!-- 依賴注入 -->  
    <constructor-arg ref="userService"></constructor-arg>  
</bean>  
<bean name="userService" class="com.learning.dao.impl.UserServiceImpl"></bean>  

3.註解注入

@Controller
public class UserController {
    // 使用註解自動注入
    @Autowired()
    private UserService userService;
    // do something
}
// 創建依賴對象
@Service
public class UserService {
   // do something 
}

創建依賴對象的常見註解:@Component、@Controller、@Service、@Repository。

總結:可以看出註解的方式要比傳統的 XML(setter 和構造器注入)實現注入更爲方便,同時註解方式也是官方力推的依賴注入最佳使用方式。

面向切面編程(AOP)
  面向切面編程(Aspect Oriented Programming,AOP),它就好比將系統按照功能分類,每一個類別就是一個“切面”,我們再針對不同的切面制定相應的規則,類似開發模式被稱爲面向切面編程。

AOP 使用場景

  • 日誌系統
  • 安全統一效驗

AOP 優點

  • 集中處理某一類問題,方便維護
  • 邏輯更加清晰
  • 降低模塊間的耦合度

AOP 相關概念

  • Join point:連接點,程序執行期間的某一個點,例如執行方法或處理異常時候的點,在 Spring AOP 中,連接點總是表示方法的執行。
  • Join point:連接點,程序執行期間的某一個點,例如執行方法或處理異常時候的點,在 Spring AOP 中,連接點總是表示方法的執行。
  • Advice:通知,通知分爲方法執行前通知,方法執行後通知、環繞通知等。許多 AOP 框架(包括 Spring)都將通知建模爲攔截器,在連接點周圍維護一系列攔截器(形成攔截器鏈),對連接點的方法進行增強。
  • Pointcut:切點,匹配連接點(Join point)的表達式,是 AOP 的核心,並且 Spring 默認使用 AspectJ 作爲切入點表達式語言。
  • Aspect:切面,是一個跨越多個類的模塊化的關注點,它是通知(Advice)和切點(Pointcut)合起來的抽象,它定義了一個切點(Pointcut)用來匹配連接點(Join point),也就是需要對需要攔截的那些方法進行定義。
  • Target object:目標對象,被一個或者多個切面(Aspect)通知的對象,也就是需要被 AOP 進行攔截對方法進行增強(使用通知)的對象,也稱爲被通知的對象。由於在 AOP 裏面使用運行時代理,因而目標對象一直是被代理的對象。
  • AOP proxy:AOP 代理,爲了實現切面(Aspect)功能使用 AOP 框架創建一個對象,在 Spring 框架裏面一個 AOP 代理指的是 JDK 自身的動態代理或 CGLIB 實現的動態代理。
  • Weaving:把切面加入到對象,並創建出代理對象的過程。
  • Advisor:一個 Advisor 相當於一個小型的切面,不同的是它只有一個通知(Advice),Advisor 在事務管理裏面會經常遇到。

AOP 代碼實現

  AOP 的示例就以開車爲例,開車的完成流程是這樣的:巡視車體及周圍情況 → 發動 → 開車 → 熄火 → 鎖車。當然我們的主要目的是“開車”,但在開車之前和開完車之後,我們要做一些其他的工作,這些“其他”的工作,可以理解爲 AOP 編程。

1.創建類和方法

package com.learning.aop;
import org.springframework.stereotype.Component;

@Component("person")
public class Person {
    public void drive() {
        System.out.println("開車");
    }
}

2.創建 AOP 攔截

package com.learning.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Component
@Aspect
public class CarAop {
    @Before("execution(* com.learning.aop.Person.drive())")
    public void before() {
        System.out.println("巡視車體及周圍情況");
        System.out.println("發動");
    }
    @After("execution(* com.learning.aop.Person.drive())")
    public void after() {
        System.out.println("熄火");
        System.out.println("鎖車");
    }
}

3.XML 配置注入掃描包路徑

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
    <context:component-scan base-package="com.learning"/>
    <aop:aspectj-autoproxy/>
</beans>

4.創建測試類

package com.learning.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class PersonTest {
    public static void main(String[] args) {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("applicationContext.xml");
        Person landlord = context.getBean("person", Person.class);
        landlord.drive();
    }
}

運行測試代碼,執行結果如下:

巡視車體及周圍情況

發動

開車

熄火

鎖車

AspectJ 註解說明:

  • @Before — 前置通知,在連接點方法前調用;
  • @Around — 環繞通知,它將覆蓋原有方法,但是允許你通過反射調用原有方法;
  • @After — 後置通知,在連接點方法後調用;
  • @AfterReturning — 返回通知,在連接點方法執行並正常返回後調用,要求連接點方法在執行過程中沒有發生異常;
  • @AfterThrowing — 異常通知,當連接點方法異常時調用。

筆試面試題

1.@Value 註解的作用是什麼?

答:基於 @Value 的註解可以讀取 properties 配置文件,使用如下:

@Value("#{configProperties['jdbc.username']}")

private String userName;

以上爲讀取 configProperties 下的 jdbc.username 配置。

2.Spring 通知類型有哪些?

答:Spring 通知類型總共有 5 種:前置通知、環繞通知、後置通知、異常通知、最終通知。

  • 前置通知(Before advice):在目標方法執行之前執行的通知。在某連接點( join point )之前執行的通知,但這個通知不能阻止連接點前的執行(除非它拋出一個異常)。
  • 環繞通知(Around Advice):在目標方法執行之前和之後都可以執行額外代碼的通知,也可以選擇是否繼續執行連接點或直接返回它們自己的返回值或拋出異常來結束執行。
  • 後置通知(After (finally) advice):目標方法執行之後(某連接點退出的時候)執行的通知(不論是正常返回還是異常退出)。
  • 異常後通知(After throwing advice):在方法拋出異常退出時執行的通知。
  • 最終通知(After returning advice):在某連接點(join point)正常完成後執行的通知,例如,一個方法沒有拋出任何異常,正常返回。

3.怎麼理解 Spring 中的 IOC 容器?

答:Spring IOC 就是把創建對象的權利交給框架去控制,而不需要人爲的去創建,這樣就實現了可插拔式的接口編程,有效地降低代碼的耦合度,降低了擴展和維護的成本。

比如,去某地旅遊不再用自己親自爲訂購 A 酒店還是 B 酒店而發愁了,只需要把住店的需求告訴給某個託管平臺,這個託管平臺就會幫你訂購一個既便宜又舒適的酒店,而這個幫你訂購酒店的行爲就可以稱之爲控制反轉。

4.怎麼理解 Spring 中的依賴注入?

答:依賴注入是指組件之間的依賴關係由容器在運行期決定,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並非爲軟件系統帶來更多功能,而是爲了提升組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。

5.IoC 和 DI 有什麼關係?

答:IoC 是 Spring 中一個極爲重要的概念,提供了對象管理的功能,從而省去了人爲創建麻煩,而 DI 正是實現 IoC 的方法和手段。

6.@Component 和 @Bean 有什麼區別?

答:它們的作用對象不同:@Component 作用於類,而 @Bean 註解作用於方法。

@Component 通常是通過類路徑掃描來自動偵測和裝配對象到 Spring 容器中,比如 @ComponentScan 註解就是定義掃描路徑中的類裝配到 Spring 的 Bean 容器中;@Bean 註解是告訴 Spring 這是某個類的實例,當我需要用它的時把它給我,@Bean 註解比 @Component 註解自定義性更強,很多地方我們只能通過 @Bean 註解來註冊 Bean,比如當我們引用第三方庫中的類需要裝配到 Spring容器時,則只能通過 @Bean 來實現,比如以下示例,只能通過 @Bean 註解來實現:

public class WireThirdLibClass {
    @Bean
    public ThirdLibClass getThirdLibClass() {
        return new ThirdLibClass();
    }
}

7.Spring 中 bean 的作用域有幾種類型?

答:Spring 中 bean 的作用域有四種類型,如下列表:

  • 單例(Singleton):整個應用程序,只創建 bean 的一個實例;
  • 原型(Prototype):每次注入都會創建一個新的 bean 實例;
  • 會話(Session):每個會話創建一個 bean 實例,只在 Web 系統中有效;
  • 請求(Request):每個請求創建一個 bean 實例,只在 Web 系統中有效。
    Spring 默認的是單例模式。

8.什麼是 Spring 的內部 bean?

答:當一個 bean 僅被用作另一個 bean 的屬性時,它能被聲明爲一個內部 bean,爲了定義 inner Bean,在 Spring 的基於 XML 的配置元數據中,可以在 <property/><constructor-arg/> 元素內使用 <bean/> 元素,內部 bean 通常是匿名的,它們的 Scope 一般是 prototype。

9.Spring 注入方式有哪些?

答:Spring 的注入方式包含以下五種:

  • setter 注入
  • 構造方法注入
  • 註解注入
  • 靜態工廠注入
  • 實例工廠注入

其中最常用的是前三種,官方推薦使用的是註解注入,相對使用更簡單,維護成本更低,更直觀。

10.在 Spring 中如何操作數據庫?

答:在 Spring 中操作數據庫,可以使用 Spring 提供的 JdbcTemplate 對象,JdbcTemplate 類提供了很多便利的方法,比如把數據庫數據轉變成基本數據類型或對象,執行自定義的 SQL 語句,提供了自定義的數據錯誤處理等,JdbcTemplate 使用示例如下:

@Autowired
private JdbcTemplate jdbcTemplate;
// 新增
@GetMapping("save")
public String save(){
    String sql = "INSERT INTO USER (USER_NAME,PASS_WORD) VALUES ('laowang','123')";
    int rows = jdbcTemplate.update(sql);
    return "執行成功,影響" + rows + "行";
}
// 刪除
@GetMapping("del")
public String del(int id){
    int rows= jdbcTemplate.update("DELETE FROM  USER  WHERE ID = ?",id);
    return "執行成功,影響" + rows + "行";
}
// 查詢
@GetMapping("getMapById")
public Map getMapById(Integer id){
    String sql = "SELECT * FROM USER WHERE ID = ?";
    Map map= jdbcTemplate.queryForMap(sql,id);
    return map;
}

11.Spring 的 JdbcTemplate 對象和 JDBC 有什麼區別?

答:Spring 的 JdbcTemplate 是對 JDBC API 的封裝,提供更多的功能和更便利的操作,比如 JdbcTemplate 擁有:

  • JdbcTemplate 是線程安全的;
  • 實例化操作比較簡單,僅需要傳遞 DataSource;
  • 自動完成資源的創建和釋放工作;
  • 創建一次 JdbcTemplate,到處可用,避免重複開發。

12.Spring 有幾種實現事務的方式?

答:Spring 實現事務有兩種方式:編程式事務和聲明式事務。

編程式事務,使用 TransactionTemplate 或 PlatformTransactionManager 實現,示例代碼如下:

private final TransactionTemplate transactionTemplate;
public void add(User user) throws Exception{
    // Spring編碼式事務,回調機制
    transactionTemplate.execute(new TransactionCallback<Object>() {
        @Override
        public Object doInTransaction(TransactionStatus status) {
            try {
                userMapper.insertSelective(user);
            } catch (Exception e) {
                // 異常,設置爲回滾
                status.setRollbackOnly();
                throw e;
            }
            return null;
        }
    });
}

如果有異常,調用 status.setRollbackOnly() 回滾事務,否則正常執行 doInTransaction() 方法,正常提交事務。
如果事務控制的方法不需要返回值,就可以使用 TransactionCallbackWithoutResult(TransactionCallback 接口的抽象實現類)示例代碼如下:

public void add(User user) throws Exception {
    // Spring編碼式事務,回調機制
    transactionTemplate.execute(new TransactionCallbackWithoutResult() {
        @Override
        protected void doInTransactionWithoutResult(TransactionStatus status) {
            try {
                userMapper.insertSelective(user);
            } catch (Exception e) {
                // 異常,設置爲回滾
                status.setRollbackOnly();
                throw e;
            }
        }
    });
}

聲明式事務,底層是建立在 Spring AOP 的基礎上,在方式執行前後進行攔截,並在目標方法開始執行前創建新事務或加入一個已存在事務,最後在目標方法執行完後根據情況提交或者回滾事務。
聲明式事務的優點:不需要編程,減少了代碼的耦合,在配置文件中配置並在目標方法上添加 @Transactional 註解來實現,示例代碼如下:

@Transactional
public void save() {
    User user = new User("laowang");
    userMapper.insertSelective(user);
    if (true) {
        throw new RuntimeException("異常");
    }
}

拋出異常,事務會自動回滾,如果方法正常執行,則會自動提交事務。

13.Spring 事務隔離級別有哪些?

答:Spring 的注入方式包含以下五種:

  • ISOLATION_DEFAULT:用底層數據庫的設置隔離級別,數據庫設置的是什麼我就用什麼;
  • ISOLATIONREADUNCOMMITTED:未提交讀,最低隔離級別、事務未提交前,就可被其他事務讀取(會出現幻讀、髒讀、不可重複讀);
  • ISOLATIONREADCOMMITTED:提交讀,一個事務提交後才能被其他事務讀取到(會造成幻讀、不可重複讀),SQL server 的默認級別;
  • ISOLATIONREPEATABLEREAD:可重複讀,保證多次讀取同一個數據時,其值都和事務開始時候的內容是一致,禁止讀取到別的事務未提交的數據(會造成幻讀),MySQL 的默認級別;
  • ISOLATION_SERIALIZABLE:序列化,代價最高最可靠的隔離級別,該隔離級別能防止髒讀、不可重複讀、幻讀。
    默認值爲 ISOLATION_DEFAULT 遵循數據庫的事務隔離級別設置。

14.Spring 聲明式事務無效可能的原因有哪些?

答:可能的原因如下:

  • MySQL 使用的是 MyISAM 引擎,而 MyISAM 是不支持事務的;
  • @Transactional 使用在非 public 方法上,@Transactional 註解只能支持 public 級別,其他類型聲明的事務不會生效;
  • @Transactional 在同一個類中無事務方法 A() 內部調用有事務方法 B(),那麼此時 B() 事物不會生效。Spring 中的 AOP 的底層實現原理是什麼?

答:Spring AOP 的底層實現原理就是動態代理。Spring AOP 的動態代理有兩種實現方式,對於接口使用的是 JDK 自帶的動態代理來實現的,而對比非接口使用的是 CGLib 來實現的,關於動態代理的詳細內容,可參考前面 反射與動態代理 這篇文章。

15.Spring 中的 Bean 是線程安全的嗎?

答:Spring 中的 Bean 默認是單例模式,Spring 框架並沒有對單例 Bean 進行多線程的封裝處理,因此默認的情況 Bean 並非是安全的,最簡單保證 Bean 安全的舉措就是設置 Bean 的作用域爲 Prototype(原型)模式,這樣每次請求都會新建一個 Bean。

16.說一下 Spring 中 Bean 的生命週期?

答:Spring 中 Bean 的生命週期如下:

  • ① 實例化 Bean:對於 BeanFactory 容器,當客戶向容器請求一個尚未初始化的 Bean 時,或初始化 Bean 的時候需要注入另一個尚未初始化的依賴時,容器就會調用 createBean 進行實例化。對於 ApplicationContext 容器,當容器啓動結束後,通過獲取 BeanDefinition 對象中的信息,實例化所有的 Bean;
  • ② 設置對象屬性(依賴注入):實例化後的對象被封裝在 BeanWrapper 對象中,緊接着 Spring 根據 BeanDefinition 中的信息以及通過 BeanWrapper 提供的設置屬性的接口完成依賴注入;
  • ③ 處理 Aware 接口:Spring 會檢測該對象是否實現了 xxxAware 接口,並將相關的 xxxAware 實例注入給 Bean:
  • 如果這個 Bean 已經實現了 BeanNameAware 接口,會調用它實現的 setBeanName(String BeanId) 方法,此處傳遞的就是 Spring 配置文件中 Bean 的 id 值;
  • 如果這個 Bean 已經實現了 BeanFactoryAware 接口,會調用它實現的 setBeanFactory() 方法,傳遞的是 Spring 工廠自身;
  • 如果這個 Bean 已經實現了 ApplicationContextAware 接口,會調用 setApplicationContext(ApplicationContext) 方法,傳入 Spring 上下文;
  • ④ BeanPostProcessor:如果想對 Bean 進行一些自定義的處理,那麼可以讓 Bean 實現了 BeanPostProcessor 接口,那將會調用 postProcessBeforeInitialization(Object obj, String s) 方法;
  • ⑤ InitializingBean 與 init-method:如果 Bean 在 Spring 配置文件中配置了 init-method 屬性,則會自動調用其配置的初始化方法;
  • ⑥ 如果這個 Bean 實現了 BeanPostProcessor 接口,將會調用 postProcessAfterInitialization(Object obj, String s) 方法;由於這個方法是在 Bean 初始化結束時調用的,因而可以被應用於內存或緩存技術;

以上幾個步驟完成後,Bean 就已經被正確創建了,之後就可以使用這個 Bean 了。

  • ⑦ DisposableBean:當 Bean 不再需要時,會經過清理階段,如果 Bean 實現了 DisposableBean 這個接口,會調用其實現的 destroy() 方法;
  • ⑧ destroy-method:最後,如果這個 Bean 的 Spring 配置中配置了 destroy-method 屬性,會自動調用其配置的銷燬方法。

17.Spring 有哪些優點?

答:Spring 優點如下:

  • 開源免費的熱門框架,穩定性高、解決問題成本低;
  • 方便集成各種優秀的框架;
  • 降低了代碼耦合性,通過 Spring 提供的 IoC 容器,我們可以將對象之間的依賴關係交由 Spring 進行控制,避免硬編碼所造成的過度程序耦合;
  • 方便程序測試,在 Spring 裏,測試變得非常簡單,例如:Spring 對 Junit 的支持,可以通過註解方便的測試 Spring 程序;
  • 降低 Java EE API 的使用難度,Spring 對很多難用的 Java EE API(如 JDBC、JavaMail、遠程調用等)提供了一層封裝,通過 Spring 的簡易封裝,讓這些 Java EE API 的使用難度大爲降低。

18.Spring 和 Struts 的區別?

答:Spring 和 Struts 區別如下:

Spring 特性如下:

  • 具備 IOC/DI、AOP 等通用能力,提高研發效率
  • 除了支持 Web 層建設以外,還提供了 J2EE 整體服務
  • 方便與其他不同技術結合使用,如 Hibernate、MyBatis 等
  • Spring 攔截機制是方法級別

Struts 特性如下:

  • 是一個基於 MVC 模式的一個 Web 層的處理
  • Struts 攔截機制是類級別

19.Spring、SpringBoot、SpringCloud 的區別是什麼?

答:它們的區別如下:

  • Spring Framework 簡稱 Spring,是整個 Spring 生態的基礎。
  • Spring Boot 是一個快速開發框架,讓開發者可以迅速搭建一套基於 Spring 的應用程序,並且將常用的 Spring 模塊以及第三方模塊,如 MyBatis、Hibernate 等都做了很好的集成,只需要簡單的配置即可使用,不需要任何的 XML 配置文件,真正做到了開箱即用,同時默認支持 JSON 格式的數據,使用 Spring Boot 進行前後端分離開發也非常便捷。
  • Spring Cloud 是一套整合了分佈式應用常用模塊的框架,使得開發者可以快速實現微服務應用。作爲目前非常熱門的技術,有關微服務的話題總是在各種場景下被大家討論,企業的招聘信息中也越來越多地出現對於微服務架構能力的要求。

20.Spring 中都是用了哪些設計模式?

答:Spring 中使用的設計模式如下:

  • 工廠模式:通過 BeanFactory、ApplicationContext 來創建 bean 都是屬於工廠模式;
  • 單例、原型模式:創建 bean 對象設置作用域時,就可以聲明 Singleton(單例模式)、Prototype(原型模式);
  • 察者模式:Spring 可以定義一下監聽,如 ApplicationListener 當某個動作觸發時就會發出通知;
  • 責任鏈模式:AOP 攔截器的執行;
  • 策略模式:在創建代理類時,如果代理的是接口使用的是 JDK 自身的動態代理,如果不是接口使用的是 CGLIB 實現動態代理。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章