Java單體應用 - 常用框架 - 02.Spring

原文地址:http://www.work100.net/training/monolithic-frameworks-spring.html
更多教程:光束雲 - 免費課程

Spring

序號 文內章節 視頻
1 概述 -
2 體系結構 -
3 特點 -
4 Spring與IoC -
5 第一個Spring應用程序 -

請參照如上章節導航進行閱讀

1.概述

Spring 的主要作用就是爲代碼“解耦”,降低代碼間的耦合度。

根據功能的不同,可以將一個系統中的代碼分爲 主業務邏輯系統級業務邏輯 兩類,它們各自具有鮮明的特點:

  • 主業務代碼間邏輯聯繫緊密,有具體的專業業務應用場景,複用性相對較低;
  • 系統級業務相對功能獨立,沒有具體的專業業務應用場景,主要是爲主業務提供系統級服務,如日誌、安全、事務等,複用性強。

Spring 根據代碼的功能特點,將降低耦合度的方式分爲了兩類:IoCAOP

  • IoC 使得主業務在相互調用過程中,不用再自己維護關係了,即不用再自己創建要使用的對象了。而是由 Spring 容器統一管理,自動“注入”。
  • 而 AOP 使得系統級服務得到了最大複用,且不用再由程序員手工將系統級服務“混雜”到主業務邏輯中了,而是由 Spring 容器統一完成“織入”。

Spring 是於 2003 年興起的一個輕量級的 Java 開發框架,它是爲了解決企業應用開發的複雜性而創建的。
Spring 的核心是控制反轉(IoC)和麪向切面編程(AOP)。

簡單來說,Spring 是一個分層的 Java SE/EE full-stack(一站式)輕量級開源框架。

2.體系結構

Spring體系結構 - 光束雲 - work100.net

Spring 由 20 多個模塊組成,它們可以分爲數據訪問/集成(Data Access/Integration)、Web、面向切面編程(AOP, Aspects)、應用服務器設備管理(Instrumentation)、消息發送(Messaging)、核心容器(Core Container)和測試(Test)。

3.特點

非侵入式

所謂非侵入式是指,Spring 框架的 API 不會在業務邏輯上出現,即業務邏輯是 POJO。
由於業務邏輯中沒有 Spring 的 API,所以業務邏輯可以從 Spring 框架快速的移植到其他框架, 即與環境無關。

容器

Spring 作爲一個容器,可以管理對象的生命週期、對象與對象之間的依賴關係。可以通過配置文件,來定義對象,以及設置與其他對象的依賴關係。

IoC

控制反轉(Inversion of Control),即創建被調用者的實例不是由調用者完成,而是由 Spring 容器完成,並注入調用者。

當應用了 IoC,一個對象依賴的其它對象會通過被動的方式傳遞進來,而不是這個對象自己創建或者查找依賴對象。即,不是對象從容器中查找依賴,而是容器在對象初始化時不等對象請求就主動將依賴傳遞給它。

AOP

面向切面編程(AOP,Aspect Orient Programming),是一種編程思想,是面向對象編程 OOP 的補充。很多框架都實現了對 AOP 編程思想的實現。Spring 也提供了面向切面編程的豐富支持,允許通過分離應用的業務邏輯與系統級服務(例如日誌和事務管理)進行開發。應用對象只實現它們應該做的——完成業務邏輯——僅此而已。它們並不負責其它的系統級關注點,例如日誌或事務支持。

我們可以把日誌、安全、事務管理等服務理解成一個“切面”,那麼以前這些服務一直是直接寫在業務邏輯的代碼當中的,這有兩點不好:首先業務邏輯不純淨;其次這些服務被很多業務邏輯反覆使用,完全可以剝離出來做到複用。那麼 AOP 就是這些問題的解決方案, 可以把這些服務剝離出來形成一個“切面”,以期複用,然後將“切面”動態的“織入”到業務邏輯中,讓業務邏輯能夠享受到此“切面”的服務。

4.Spring與IoC

控制反轉(IoC,Inversion of Control),是一個概念,是一種思想。指將傳統上由程序代碼直接操控的對象調用權交給容器,通過容器來實現對象的裝配和管理。控制反轉就是對對象控制權的轉移,從程序代碼本身反轉到了外部容器。

IoC 是一個概念,是一種思想,其實現方式多種多樣。當前比較流行的實現方式有兩種: 依賴注入和依賴查找。依賴注入方式應用更爲廣泛。

  • 依賴查找:Dependency Lookup,DL,容器提供回調接口和上下文環境給組件,程序代碼則需要提供具體的查找方式。比較典型的是依賴於 JNDI 系統的查找。
  • 依賴注入:Dependency Injection,DI,程序代碼不做定位查詢,這些工作由容器自行完成。

依賴注入 DI 是指程序運行過程中,若需要調用另一個對象協助時,無須在代碼中創建被調用者,而是依賴於外部容器,由外部容器創建後傳遞給程序。

Spring 的依賴注入對調用者與被調用者幾乎沒有任何要求,完全支持 POJO 之間依賴關係的管理。

依賴注入是目前最優秀的解耦方式。依賴注入讓 Spring 的 Bean 之間以配置文件的方式組織在一起,而不是以硬編碼的方式耦合在一起的。

5.第一個Spring應用程序

5.1.構建項目結構

創建一個文件夾爲 hello-spring 的項目,然後增加 pom.xml 文件,代碼如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>net.work100.training.stage2</groupId>
    <artifactId>hello-spring</artifactId>
    <version>1.0.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.3.RELEASE</version>
        </dependency>
    </dependencies>
</project>

增加 org.springframework:spring-context 依賴

然後構建項目結構,並將 pom.xml 文件託管到 Maven,如下圖:

項目結構 - 光束雲 - work100.net

5.2.代碼實現

創建 UserService 接口

UserService.java 文件代碼如下:

package net.work100.training.stage2.hello.spring.service;

/**
 * <p>Title: UserService</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-12 13:32
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-12   liuxiaojun     初始創建
 * -----------------------------------------------
 */
public interface UserService {
    void sayHi();
}

創建 UserServiceImpl 實現

UserServiceImpl.java 文件代碼如下:

package net.work100.training.stage2.hello.spring.service.impl;

import net.work100.training.stage2.hello.spring.service.UserService;

/**
 * <p>Title: UserServiceImpl</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-12 13:32
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-12   liuxiaojun     初始創建
 * -----------------------------------------------
 */
public class UserServiceImpl implements UserService {
    public void sayHi() {
        System.out.println("Hello Spring");
    }
}

5.3.配置 Spring

src/main/resources 目錄下創建 spring-context.xml 配置文件,從現在開始類的實例化工作交給 Spring 容器管理(IoC),配置文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<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="userService" class="net.work100.training.stage2.hello.spring.service.impl.UserServiceImpl" />
</beans>

5.4.測試 Spring IOC

創建一個 MyTest 測試類,測試對象是否能夠通過 Spring 來創建,代碼如下:

package net.work100.training.stage2.hello.spring;

import net.work100.training.stage2.hello.spring.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * <p>Title: MyTest</p>
 * <p>Description: </p>
 *
 * @author liuxiaojun
 * @date 2020-02-12 13:35
 * ------------------- History -------------------
 * <date>      <author>       <desc>
 * 2020-02-12   liuxiaojun     初始創建
 * -----------------------------------------------
 */
public class MyTest {
    public static void main(String[] args) {
        // 獲取 Spring 容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-context.xml");

        // 從 Spring 容器中獲取對象
        UserService userService = (UserService)applicationContext.getBean("userService");
        userService.sayHi();
    }
}

5.5.運行

運行結果如下:

Hello Spring

5.6.源碼獲取

實例源碼已經託管到如下地址:


上一篇:Bootstrap

下一篇:JUnit


如果對課程內容感興趣,可以掃碼關注我們的 公衆號QQ羣,及時關注我們的課程更新

公衆號
QQ交流羣

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章