Android的核心運行容器,認識Spring核心容器IoC/DI

 2023-10-06 阅读 26 评论 0

摘要:對于 Java 編程來說,使用 Spring 能完成的更加快速,更容易并更安全。Spring 專注于速度,便捷與開發效率,也正是如此,讓Spring成為了全世界最流行的 Java 框架。從配置到安全,web應用到大數據,不管你的應用架構需要啥玩意&#

對于 Java 編程來說,使用 Spring 能完成的更加快速,更容易并更安全。Spring 專注于速度,便捷與開發效率,也正是如此,讓Spring成為了全世界最流行的 Java 框架。從配置到安全,web應用到大數據,不管你的應用架構需要啥玩意,Spring都有合適的開發框架來幫你搭建項目。Spring是基于模塊化設計的,所以你可以從最小集開始,只使用你需要的。我們主要學習其中 Spring Framework 和Spring Boot

1. Spring Framework背景介紹

Spring專注于為 Java 企業應用提供一站式的開發框架,目的是讓 Java 企業開發更加便捷,安全與高效。 Spring Framework 屬于其中最基礎,最核心的部分,Spring下的其他大部分框架都依賴 Spring Framework 。

Android的核心運行容器,在這里插入圖片描述
對于整個Spring Framework來說,是學習、使用Spring生態項目(如Spring Boot、Spring Cloud等)的基石。也就是說,我們要引入其他Spring項目作為我們的依賴框架時,也會使用Spring Framework。以上子模塊包括的內容我們只學習其中最重要的三個部分:Core Container、AOP、WebMVC

2. Core Container(核心容器)

以前我們操作對象都需要手動的 new 對象,由對象的作用域決定對象的生命周期。使用Spring后,由框架提供了統一的容器來實例化、管理這些對象,并自動組織對象與對象間的關系。這種容器稱為IoC容器,有些地方也叫Spring Bean容器、Spring容器。

2.1 IoC / DI

什么是IoC?

  • java的instanceof語句?IoC(inversion of Control),既“控制反轉”,是面向對象的一種設計原則,可以用來減低計算機代碼的耦合度

  • 系統中通過引入實現了IoC模式的IoC容器,即可由IoC容器來管理對象的生命周期、依賴關系等,從而使得應用程序的配置和依賴性規范與實際的應用程序代碼分離

  • 以前手動new對象,并設置對象中屬性的方式,控制權是掌握在應用程序自身。現在則全部轉移到了容器,由容器來統一進行管理對象。因為控制權發生了扭轉,所以叫“控制反轉”。

java結構體定義。什么是DI?

DI(Dependency Injection)既“依賴注入”,是實現IoC的方法之一,所謂依賴注入,就是有IOC容器在運行期間,動態的將某種依賴關系注入到對象當中

注意:依賴注入(DI)和控制反轉(IoC)是從不同的角度的描述的同一件事情,就是指通過引入 IoC 容
器,利用依賴關系注入的方式,實現對象之間的解耦。

3. Spring容器使用流程

舉例說明IoC容器的實現方式有哪些,Spring容器的API有 BeanFactory 和 ApplicationContext 兩大類,他們都是頂級接口。其中ApplicationContext 是 BeanFactory 的子接口。

  1. 首選創建衣Maven項目,名稱為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>org.example</groupId><artifactId>spring-study</artifactId><version>1.0-SNAPSHOT</version><properties><java.version>1.8</java.version><maven.compiler.source>${java.version}</maven.compiler.source><maven.compiler.target>${java.version}</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><spring-framework.version>5.2.10.RELEASE</spring-framework.version></properties><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>${spring-framework.version}</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>${spring-framework.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.16</version></dependency></dependencies><build><plugins><!-- 明確指定一些插件的版本,以免受到 maven 版本的影響 --><plugin><artifactId>maven-clean-plugin</artifactId><version>3.1.0</version></plugin><plugin><artifactId>maven-compiler-plugin</artifactId><version>3.8.1</version></plugin><plugin><artifactId>maven-deploy-plugin</artifactId><version>2.8.2</version></plugin><plugin><artifactId>maven-install-plugin</artifactId><version>2.5.2</version></plugin><plugin><artifactId>maven-jar-plugin</artifactId><version>3.2.0</version></plugin><plugin><artifactId>maven-resources-plugin</artifactId><version>3.1.0</version></plugin><plugin><artifactId>maven-site-plugin</artifactId><version>3.3</version></plugin><plugin><artifactId>maven-surefire-plugin</artifactId><version>2.22.2</version></plugin></plugins></build>
</project>
  1. 準備Spring配置文件
    在src/main/resources文件下,創建一個beans.xml文件(如果創建的resources文件,那么就自己創建一個,然后再配置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"xsi:schemaLocation="http://www.springframework.org/schema/beanshttps://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttps://www.springframework.org/schema/context/spring-context.xsd"><context:component-scan base-package="org.example"/></beans>
  1. 準備啟動類入口

Spring提供了通過xml配置文件,來定義Bean,但是定義Bean的方式需要通過包掃描的方式注冊到容器中
既在java源代碼下創建一個org包,然后創建一個example包,在example下創建一個名為APP的Class類

package org.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {//根據Spring配置文件路徑創建容器:應用上下文對象ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//關閉容器((ClassPathXmlApplicationContext) context).close();}
}

4. 初始化/注冊bean

4.1 方式一:類注解

在類上使用注解 @Controller , @Service , @Repository , @Component 。需要保證該類會被Spring
掃描到,這種定義方式默認會注冊一個名稱為類名首字母小寫的Bean對象到容器中。

如:我們在org.example包下創建的一個包為dao里面在寫一個類名為LoginRepository的類,然后再類名前面加上注解@Repository,此時就會在容器里面注冊一個名為 loginRepository 的對象到容器中(也即是首字母小寫)

package org.example.dao;
import org.example.model.User;
import org.springframework.stereotype.Repository;
@Repository
public class LoginRepository {
}

定義好了Bean對象,注冊到容器中以后,就可以獲取Bean對象了,在入口類 org.example.App 中,可以通過 ApplicationContext 對象獲取Bean。有兩種方式獲取:

  1. 通過類型獲取:這種獲取參數要求該類型的Bean只能有一個
  2. 通過名稱獲取:同樣一個類型的Bean可以有多個

如:

import org.example.dao.LoginRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class App {public static void main(String[] args) {//根據Spring配置文件路徑創建容器:應用上下文對象ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");//通過名稱獲取LoginRepository loginRepository = (LoginRepository) context.getBean("loginRepository");//通過類型獲取LoginRepository loginRepository1 = context.getBean(LoginRepository.class);//關閉容器((ClassPathXmlApplicationContext) context).close();}
}
方式二:@Bean

當前類被 Spring 掃描到時,可以在方法上使用 @Bean 注解,通過方法返回類型,也可以定義、注冊
Bean對象,默認使用方法名作為Bean的名稱。

方式三:@Configuration

在類被Spring掃描到時,使用 @Configuration 注解,可以注冊一個配置類到容器中。配置類一般用來自定義配置某些資源
如:

package org.example.config;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
}

5. 依賴注入

5.1 屬性注入

當前類被 Spring 掃描到時,可以在屬性上使用 @Autowired 注解,會將容器中的Bean對象裝配進來。
@Service
public class LoginService {@Autowiredprivate LoginRepository loginRepository; }

5.2 構造方法的注入

當前類被 Spring 掃描到時,可以在構造方法上使用 @Autowired 注解,作用也是和setter方法類似,
會將容器中的Bean對象注入方法參數。

@Service
public class LoginServiceByConstructor {private LoginRepository loginRepository;@Autowiredpublic LoginServiceByConstructor(LoginRepository loginRepository){System.out.printf("LoginServiceByConstructor: %s%n", loginRepository);this.loginRepository = loginRepository;}
}

5.3 注入指定的Bean:@Qualifier

同類型的Bean有多個時,注入該類型Bean需要指定Bean的名稱:
  • 屬性名或方法參數名設置為Bean的名稱
  • 屬性名或方法參數設置 @Qualifier(“名稱”) 注解,注解內的字符串是Bean對象的名稱
    如:
    @Autowiredprivate LoginService loginService;@Autowired@Qualifier("user1")private User u;@Autowiredprivate User user1;

6. Bean的作用域

Spring 容器在初始化一個 Bean 的實例時,同時會指定該實例的作用域。Spring有6個作用域,最后四種是基于Spring WebMVC生效

1. singleton

描述:該作用域下的Bean在IoC中只存在一個實例:獲取Bean(applicationContext.getBean等方法獲取),及裝配Bean(即通過@Autowired注入)都是同一個對象。

場景:通常無狀態的Bean使用該作用域,無狀態表示Bean對象的屬性狀態不需要更新

備注:Spring默認選擇該作用域

2. prototype

描述:每次對該作用域下的Bean的請求都會創建一個新的實例:獲取Bean(applicationContext.getBean等方法獲取),及裝配Bean(即通過@Autowired注入)都是新的對象實例。

場景:通常有狀態的Bean使用該作用域

3. request

描述:每次http請求會創建新的Bean實例,類似于prototype

描述:每次http請求會創建新的Bean實例,類似于prototype

場景:一次http的請求和響應的共享Bean

4. session

描述:在一個http session中,定義一個Bean實例

場景:用戶回話的共享Bean, 比如:記錄一個用戶的登陸信息

備注:限定SpringMVC中使用

5. application(了解)

描述:在一個http servlet Context中,定義一個Bean實例

場景:Web應用的上下文信息,比如:記錄一個應用的共享信息

備注:限定SpringMVC中使用

6. websocket(了解)

描述:在一個HTTP WebSocket的生命周期中,定義一個Bean實例

場景:WebSocket的每次會話中,保存了一個Map結構的頭信息,將用來包裹客戶端消息頭。第一次初始化后,直到WebSocket結束都是同一個Bean。

備注:限定Spring WebSocket中使用

7. Bean的生命周期

在這里插入圖片描述

Bean的生命周期步驟

  1. 實例化Bean:通過反射調用構造方法實例化對象
  2. 依賴注入:裝配Bean的屬性
  3. 實現Aware接口的Bean,執行接口方法:如順序執行BeanNameAware、BeanFactoryAware、ApplicationContextAware的接口方法。
  4. Bean對象初始化前:循環調用實現了BeanPostProcessor接口的預初始化方法
  5. Bean對象初始化:順序執行@PostConstruct注解方法、InitializingBean接口方法、init-method方法
  6. Bean對象初始化后:循環調用實現了BeanPostProcessor接口的后初始化方法
  7. 容器關閉時,執行Bean對象的銷毀方法,順序是:@PreDestroy注解方法、DisposableBean接口

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/1/120731.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息