科技

「SpringBoot」 小談一下Spring基礎

1 Spring 基礎

1.1 Spring 概述

1.1.1 Spring 的簡史

在我的印象中,大學時期就已經有了 Spring ,整天為配置xml而揪頭髮,想想這些年,真實變化快啊

第一階段: xml 配置

在 Spring 1.x 時代 ,使用 Spring 開發,滿眼都是 xml 檔案配置的 Bean,隨著專案的擴大, 我們需要把 xml 配置檔案

分放到不同的配置檔案裡,那時候需要頻繁的在開發的類和配置檔案之間切換。

第二階段: 註解配置

在 Spring 2.x 時代 ,隨著 JDK 1.5 帶來的註解支援,Spring 提供了宣告 Bean 的註解(如:@Component、@Service),減少了配置量。

第三階段: Java 配置

從 Spring 3.x 到現在,Spring 提供了 Java 的配置能力,使用 Java 配置讓你更容易理解你配置的 Bean,我們目前放好處在這個時代,

Spring 4.x 和 Spring Boot 都推薦使用 Java 配置。

1.1.2 Spring 概述

Spring 框架是一個輕量級的企業級開發的一站式解決方案。所謂解決方案,就是可以基於 Spring 解決 Java EE 的所有問題。

Spring 框架主要提供了 IoC 容器、AOP、資料訪問、Web 開發、訊息、測試等相關技術的支援。

Spring 使用簡單的 POJO (Plain Old Java Object,即無任何限制的普通 Java 物件)來進行企業級開發。每一個被 Spring 管理的

Java 物件都被稱為 Bean,而 Spring 提供了一個 IoC 容器用來初始化物件,解決物件間的依賴管理和物件的使用。

Spring 模組 Spring 是模組化的,你可以只用你需要的 Spring 模組。1)核心容器(Core Container)

Spring-Core:核心工具類,Spring 其他模組大量使用 Spring-Core;

Spring-Beans:Spring 定義 Bean 的支援;

Spring-Context:執行時 Spring 容器;

Spring-Context-Support:Spring 對第三包的支援;

Spring-Expression:使用表示式語言在執行時查詢和操作物件。

2)AOP

Spring-AOP:基於代理的 AOP 支援;

Spring-Aspects:基於 Aspects 的 AOP 支援;

Spring-Context:執行時 Spring 容器;

Spring-Context-Support:Spring 對第三包的支援;

Spring-Expression:使用表示式語言在執行時查詢和操作物件。

3)訊息(Message)

Spring-Message:對訊息架構和協議的支援;

4)Web

Spring-Web:提供基礎的 Web 整合功能,在專案中提供 Spring 的容器;

5)資料訪問/整合(DataAccess/Integration)

Spring-JDBC:提供以 JDBC 訪問資料庫的支援;

Spring-TX:提供程式設計式和宣告式的事物支援;

Spring-ORM:提供 物件/關係對映 技術的支援;

Spring-OXM:提供 物件/XML對映 技術的支援;

Spring-JMS:提供對 JMS 的支援;

Spring 的生態 Spring 發展到現在已經不僅僅是 Spring 框架本身的內容, Spring 目前提供了大量的基於 Spring 的專案, 可以用來更深入地降低我們的開發難度,提供開發效率。目前 Spring 的生態裡有一下專案:

1)Spring Boot;使用預設開發配置來進行快速開發;

2)Spring XD:用來簡化大資料開發;

3)Spring Cloud:為分散式系統開發提供工具集;

4)Spring Data:對主流的關係型、NoSQL 資料庫的支援;

5)Spring Integration:通過訊息機制對企業整合模式(EIP)的支援;

6)Spring Batch:簡化和優化大量資料的批處理操作;

7)Spring Security:通過認證和授權保護應用;

8)Spring HATEOAS:基於 HATEOAS 原則簡化 REST 服務開發;

9)Spring Social:與社交網路API的整合

10)Spring Mobile:提供對手機裝置檢測的功能

11)Spring For Android:主要提供在 Android 消費 RESTFul API 的功能

12)Spring Web Flow:基於 Spring MVC 提供基於嚮導流程式的 Web 應用開發

13)Spring Web Services:基於協議有限的 SOAP/Web 服務

14)Spring LDAP:簡化使用 LDAP 開發

15)Spring Session:提供一個 API及實現來管理使用者會話資訊

1.2 Spring 專案快速搭建

早期,都是把依賴的 jar 包放到類路徑下,以來混亂。

為了解決依賴問題,需要專案構建工具。

目前主流的專案構建工具:Ant、Maven、Gradle等。

1.2.1 Maven 簡介

1.2.2 Maven 安裝

安裝測試安裝 mvn -v

1.2.3 Maven 的 pom.xml

Maven 是基於專案物件模型的概念運作的,所以 Maven 都有一個 pom.xml。

dependenciesdependency 元素 groupId、artifactId、version變數定義 properties編譯外掛 build -> plugins -> pluginMaven 運作方式 Maven 會自動根據 dependency 中的依賴配置,直接通過網際網路在 Maven 中心庫下載相關依賴包到 .m2 目錄下, .m2 是你的本地 Maven 倉庫。 如果你不知道你要依賴的 jar 包怎麼引用,推薦到 mavenrepository.com 網站搜尋。 如果中心倉庫沒有你需要的 jar 包,需要 把 jar 包安裝到本地倉庫mvn install:install-file -Dfile=jar包的位置 -DgroupId=上面的groupId -DartifactId=上面的artifactId -Dversion=上面的version -Dpackaging=jar

1.2.4 Spring 專案構建

Spring Tool Suite (STS)eclipse、idea、NetBeans 外掛

1.3 Spring 基礎配置

Spring 本身的四大原則:

使用 POJO 進行輕量級和最小侵入式開發通過依賴注入和基於介面程式設計實現鬆耦合通過 AOP 和預設習慣進行宣告式程式設計使用 AOP 和模板(Template)較少模式化程式碼

1.3.1 依賴注入 (依賴spring-boot-starter-web)

我們常說的控制翻轉(Invention Of Control - IoC)和 依賴注入(Dependency injection - DI)在 Spring 環境下其實是等價的。

空中翻轉是通過依賴注入實現的。依賴注入其實就是容器負責建立物件和維護物件間的依賴關係。

依賴注入目的是為了解耦,提現一種"組合"的概念。

無論 xml 配置、註解配置,還是 Java 配置,都叫配置元資料,元資料就是描述資料的資料。

Spring 容器解析這些配置元資料進行 Bean 初始化、配置和管理依賴。

宣告 Bean 的註解:

@Component 麼有明確的角色@Service 業務邏輯層@Repository 資料訪問層@Controller 表現層注入 Bean 的註解: 下面三個可以放在 set 方法 或者屬性上,我習慣放在屬性上

@Autowired Spring 提供的註解@Inject JSR-330 提供的註解@Resource JSR-250 提供的註解JSR 即 Java Specification Requests,Java 規範說明

@Configuration 聲明當前類是一個配置類@ComponentScan 自動掃描包名下所有使用 @Service @Component @Repository @Controller 的類並註冊為 Bean。

1.3.2 Java 配置

Spring 4.x 推薦使用 Java 配置,Spring Boot 樣推薦使用 Java 配置。

Java 配置通過 @Configuration 和 @Bean 來實現。

@Configuration 聲明當前類是一個配置類,相當於 Spring 的一個 xml 檔案@Bean 註解在方法上,聲明當前方法返回值為一個 Bean。執行/**

* Java 配置類

*/

@Configuration // 標註當前是一個配置類

public class JavaConfig {

/**

* 普通 Bean 注入

*/

@Bean

public UserService userService(){

return new UserService();

}

/**

* 直接將 userService 作為引數傳遞給 payService() 方法

* 在 Spring 容器中,只要容器中存在某個 Bean,就可以在另一個 Bean 宣告的方法的引數中注入

*/

@Bean

public PayService payService(UserService userService){

return new PayService(userService);

}

}

/**

* user

*/

public class UserService {

public String sayHello(){

return "user";

}

}

/**

* pay

*/

public class PayService {

private UserService userService;

public PayService(UserService userService) {

this.userService = userService;

}

public String pay(){

return userService.sayHello() + " pay";

}

}

/**

* main

*/

public class RunApplication {

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(JavaConfig.class);

UserService userService = context.getBean(UserService.class);

System.out.println(userService.sayHello());

PayService payService = context.getBean(PayService.class);

System.out.println(payService.pay());

// 輸出

// user

// user pay

}

}

1.3.3 AOP (依賴spring-boot-starter-aop)

AOP 面向切面程式設計,相對於 OOP 面向物件程式設計。

Spring AOP 的存在目的是:解耦。AOP可以讓一組類共享相同的行為。在 OOP 中只能通過繼承類和實現介面,

使得程式碼的耦合度增強,且類繼承只能是單繼承,阻礙更多行為應用到一組類上,AOP 彌補 OOP 的不足。

Spring 支援 AspectJ 的註解式切面程式設計。

@Aspect 宣告一個切面@After @Before @Around 定義建言(Advice),可直接攔截規則(切點)作為引數@Pointcut 宣告一個切點,定義攔截規則其中符合條件的每一個被攔截處為連線點(JoinPoint)攔截方式

基於註解基於方法規則

/**

* 攔截規則的註解

*/

@Target( { METHOD, FIELD, ANNOTATION_TYPE })

@Retention(RUNTIME)

public @interface Action {

String name();

}

/**

* 使用註解的被攔截類

*/

@Service

public class AnnotationService {

@Action(name = "註解式攔截的 play 操作")

public void play()

/**

* 使用方法規則的被攔截類

*/

@Service

public class MethodRuleService {

public void play()

**

* AOP 配置類

*/

@Configuration // 標註當前是一個配置類

@EnableAspectJAutoProxy // 開啟 Spring 對 AspectJ 的支援

@ComponentScan("chapter1.aop")

public class AopConfig

/**

* 切面類

*/

@Aspect // 註解宣告一個切面

@Component // 註解成為 Spring 容器管理的 Bean

@Slf4j

public class LogAspect {

/**

* 註解宣告切點

*/

@Pointcut("@annotation(chapter1.aop.Action)")

public void annotationPointCut(){}

/**

* 註解宣告一個建言,並使用 @PointCut 定義的切點

*/

@After("annotationPointCut()")

public void after(JoinPoint joinPoint){

// 通過反射可獲取註解上的屬性,執行一些業務操作

final MethodSignature signature = (MethodSignature) joinPoint.getSignature();

Method method = signature.getMethod();

Action action = method.getAnnotation(Action.class);

log.info("Action name: {}", action.name());

}

/**

* 註解宣告一個建言,直接使用攔截規則作為引數

*/

@Before("execution(* chapter1.aop.MethodRuleService.*(..))") // 所有 chapter1.aop.MethodRuleService 包下的所有方法

public void before(JoinPoint joinPoint){

final MethodSignature signature = (MethodSignature) joinPoint.getSignature();

Method method = signature.getMethod();

log.info("方法名: {}", method.getName());

}

}

/**

* AOP 執行類

*/

public class RunApplication {

public static void main(String[] args) {

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AopConfig.class);

// 2 AOP

AnnotationService annotationService = context.getBean(AnnotationService.class);

annotationService.play();

MethodRuleService methodRuleService = context.getBean(MethodRuleService.class);

methodRuleService.play();

// 輸出

// Action name: 註解式攔截的 play 操作

// 方法名: play

}

}

Reference:科技日報

看更多!請加入我們的粉絲團

轉載請附文章網址

不可錯過的話題