Spring5學習筆記— 工廠高級特性

Springgif.gif

?作者簡介:大家好,我是Leo,熱愛Java后端開發者,一個想要與大家共同進步的男人😉😉
🍎個人主頁:Leo的博客
💞當前專欄: Spring專欄
?特色專欄: MySQL學習
🥭本文內容:Spring5學習筆記— 工廠高級特性
🖥?個人小站 :個人博客,歡迎大家訪問
📚個人知識庫: 知識庫,歡迎大家訪問

1. 對象的生命周期

1.1 什么是對象的生命周期

含義:一個對象創建、存活、消亡的一個完整過程。

1.2 為什么要學習對象的生命周期

Spring 負責對象的創建、存活、銷毀,了解生命周期,有利于我們使用好Spring為我們創建的對象。

1.3 聲明周期的三個階段

1. 創建階段

  • scope="singleton"

    此時會在創建Spring工廠時,創建對象。

    注意:如果同時設置了lazy-init="true",那么會在獲取對象ctx.getBean("")時創建。

  • scope="prototype"

    Spring工廠會在獲取對象時,創建對象,即調用ctx.getBean("")方法時創建。

注意:如果有屬性需要注入(DI),會在創建完成時立即進行注入。

2. 初始化階段

創建階段完成后,Spring會調用對象的初始化方法,完成對應的初始化操作。

程序員提供初始化方法的途徑:

  1. 實現InitializingBean接口:

    //實現這個方法,完成初始化操作
    public void afterProperitesSet(){}
    
    1. 對象中提供一個普通的方法同時配置Spring配置文件:
    public void myInit(){}
    

    細節分析:

    • 如果一個對象即實現InitializingBean,同時又提供的普通的初始化方法 ,順序:

      1. InitializingBean
      2. 普通初始化方法
    • 注入一定發生在初始化操作的前面

    • 什么叫做初始化操作:資源的初始化:數據庫、IO、網絡 …

3. 銷毀階段

Spring銷毀對象ctx.close();前,會調用對象的銷毀方法,完成銷毀操作

程序員定義銷毀方法的途徑:

  1. 實現DisposableBean

    public void destroy()throws Exception{}
    
  2. 定義一個普通的銷毀方法同時配置Spring配置文件:

    public void myDestroy()throws Exception{}
    
    <bean id="" class="" init-method="" destroy-method="myDestroy"/>
    

細節分析:

  • 銷毀方法的操作只適用于 scope="singleton"
  • 銷毀操作主要指資源的釋放操作,比如io.close(); connection.close();

2. 配置文件參數化

2.1 什么是配置文件參數化

把Spring配置文件中需要經常修改的字符串信息,轉移到一個更小的配置文件中。

  1. Spring的配置文件中存在需要經常修改的字符串?
    存在 以數據庫連接相關的參數 代表
  2. 經常變化字符串,在Spring的配置文件中,直接修改
    不利于項目維護(修改)
  3. 轉移到一個小的配置文件(.properties)
    利于維護(修改)

配置文件參數化:利于Spring配置文件的維護(修改)

2.2 配置文件參數化的開發步驟:

1. 提供一個小的配置文件

# 名字:隨便
# 放置位置:隨便jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/test?useSSL=false
jdbc.username = root
jdbc.password = root

2. Spring的配置文件與小配置文件進行整合

<context:property-placeholder location="classpath:/db.properties"/>

3. 在Spring配置文件中通過${key}獲取小配置文件中對應的值

image-20200928215903162

3. 自定義類型轉換器

1. 什么是類型轉換器

Spring 提供了一種 Converter(類型轉換器)的類型轉換工具。在 Spring MVC 中,它的作用是在控制器方法對請求進行處理前,先獲取到請求發送過來的參數,并將其轉換為控制器方法指定的數據類型,然后再將轉換后的參數值傳遞給控制器方法的形參,這樣后臺的控制器方法就可以正確地獲取請求中攜帶的參數了。

Spring MVC 框架默認提供了許多內置的類型轉換器,主要包括以下幾種類型。

1.1 標量轉換器

名稱作用
StringToBooleanConverterString 到 boolean 類型轉換
ObjectToStringConverterObject 到 String 轉換,調用 toString 方法轉換
StringToNumberConverterFactoryString 到數字轉換(例如 Integer、Long 等)
NumberToNumberConverterFactory數字子類型(基本類型)到數字類型(包裝類型)轉換
StringToCharacterConverterString 到 Character 轉換,取字符串中的第一個字符
NumberToCharacterConverter數字子類型到 Character 轉換
CharacterToNumberFactoryCharacter 到數字子類型轉換
StringToEnumConverterFactoryString 到枚舉類型轉換,通過 Enum.valueOf 將字符串轉換為需要的枚舉類型
EnumToStringConverter枚舉類型到 String 轉換,返回枚舉對象的 name 值
StringToLocaleConverterString 到 java.util.Locale 轉換
PropertiesToStringConverterjava.util.Properties 到 String 轉換,默認通過 ISO-8859-1 解碼
StringToPropertiesConverterString 到 java.util.Properties 轉換,默認使用 ISO-8859-1 編碼

1.2 集合、數組相關轉換器

名稱作用
ArrayToCollectionConverter任意數組到任意集合(List、Set)轉換
CollectionToArrayConverter任意集合到任意數組轉換
ArrayToArrayConverter任意數組到任意數組轉換
CollectionToCollectionConverter集合之間的類型轉換
MapToMapConverterMap之間的類型轉換
ArrayToStringConverter任意數組到 String 轉換
StringToArrayConverter字符串到數組的轉換,默認通過“,”分割,且去除字符串兩邊的空格(trim)
ArrayToObjectConverter任意數組到 Object 的轉換,如果目標類型和源類型兼容,直接返回源對象;否則返回數組的第一個元素并進行類型轉換
ObjectToArrayConverterObject 到單元素數組轉換
CollectionToStringConverter任意集合(List、Set)到 String 轉換
StringToCollectionConverterString 到集合(List、Set)轉換,默認通過“,”分割,且去除字符串兩邊的空格(trim)
CollectionToObjectConverter任意集合到任意 Object 的轉換,如果目標類型和源類型兼容,直接返回源對象;否則返回集合的第一個元素并進行類型轉換
ObjectToCollectionConverterObject 到單元素集合的類型轉換

Spring MVC 對于基本類型(例如 int、long、float、double、boolean 以及 char 等)已經做好了基本類型轉換。因此,通常情況下 Spring MVC 提供的這些類型轉換器可以滿足開發人員大多數的類型轉換需求的。

注意:在使用內置類型轉換器時,請求參數輸入值需要與接收參數類型相兼容,否則會報 400 錯誤。

2. 類型轉換器的作用

Spring通過類型轉換器把配置文件中字符串類型的數據,轉換成對象中成員變量對應類型的數據,進而完成了注入。

image-20200418201732220

3. 為什么要自定義類型轉換器?

原因:實際應用中需要轉換某種特定的類型,且Spring內部沒有提供這種類型轉換器時,需要程序員自己定義。

4. 自定義類型轉換器的開發步驟

4.1 實現 Converter<>接口

public class MyDateConverter implements Converter<String, Date> {/*convert方法作用:String --->  DateSimpleDateFormat sdf = new SimpleDateFormat();sdf.parset(String) ---> Dateparam:source 代表的是配置文件中 日期字符串 <value>2020-10-11</value>return : 當把轉換好的Date作為convert方法的返回值后,Spring自動的為birthday屬性進行注入(賦值)*/public Date convert(String source) {Date date = null;try {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");date = sdf.parse(source);} catch (ParseException e) {e.printStackTrace();}return date;}
}

4.2 在Spring的配置文件中進行配置

<!-- 創建自定義轉換器對象 -->
<bean id="myDateConverter" class="com.yuziyan.converter.MyDateConverter"/><!-- 在Spring中注冊自定義的轉換器 -->
<!-- 目的:告知Spring框架,我們所創建的MyDateConverter是一個類型轉換器 -->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean"><property name="converters"><set><ref bean="myDateConverter"/></set></property>
</bean><!-- 上面兩步完成之后就可以直接使用了 -->

5. 細節

5.1 體會依賴注入(DI)

MyDateConverter中的日期的格式,可以通過依賴注入的方式,由配置文件完成賦值。

public class MyDateConverter implements Converter<String, Date> {private String pattern;public String getPattern() { return pattern; }public void setPattern(String pattern) { this.pattern = pattern; }/*convert方法作用:String --->  DateSimpleDateFormat sdf = new SimpleDateFormat();sdf.parset(String) ---> Dateparam:source 代表的是配置文件中 日期字符串 <value>2020-10-11</value>return : 當把轉換好的Date作為convert方法的返回值后,Spring自動的為birthday屬性進行注入(賦值)*/public Date convert(String source) {Date date = null;try {SimpleDateFormat sdf = new SimpleDateFormat(pattern);date = sdf.parse(source);} catch (ParseException e) {e.printStackTrace();}return date;}
}
<!--創建自定義類型轉換器對象-->
<bean id="myDateConverter" class="com.yuziyan.converter.MyDateConverter"><property name="pattern" value="yyyy-MM-dd"/>
</bean>
ConversionSeviceFactoryBean 定義id屬性,值必須是 conversionService

5.2 Spring框架內置日期類型的轉換器

日期格式:2020/05/01 (不支持 :2020-05-01)

6. 后置處理Bean

6.1 BeanPostProcessor的作用:

對Spring工廠所創建的對象,進行再加工。

注意:BeanPostProcessor是接口

1. BeanPostProcessor

都是在目標對象被實例化之后,并且屬性也被設置之后調用的

  • postProcessBeforeInitialization
    • 在afterPropertiesSet或者自定義的初始化方法(使用@bean注解中的initMethod()屬性或者使用xml配置)之前執行
  • postProcessAfterInitialization
    • 在afterPropertiesSet或者自定義的初始化方法之后執行(如果是從FactoryBean中獲取的對象,則只有這個方法會起作用,,postProcessBeforeInitialization以及afterPropertiesSet或者自定義的初始化方法都不會有作用)

2. InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口繼承BeanPostProcessor接口,它內部提供了3個方法,再加上BeanPostProcessor接口內部的2個方法,所以實現這個接口需要實現5個方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目標對象的實例化過程中需要處理的事情,包括實例化對象的前后過程以及實例的屬性設置

在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()方法的Object bean = resolveBeforeInstantiation(beanName, mbdToUse);方法里面執行了這個后置處理器

  • postProcessBeforeInstantiation
    • 在目標對象實例化之前調用,方法的返回值類型是Object,我們可以返回任何類型的值。由于這個時候目標對象還未實例化,所以這個返回值可以用來代替原本該生成的目標對象的實例(一般都是代理對象)。如果該方法的返回值代替原本該生成的目標對象,后續只有postProcessAfterInitialization方法會調用,其它方法不再調用;否則按照正常的流程走
  • postProcessAfterInstantiation
    • 方法在目標對象實例化之后調用,這個時候對象已經被實例化,但是該實例的屬性還未被設置,都是null。如果該方法返回false,會忽略屬性值的設置;如果返回true,會按照正常流程設置屬性值。
  • postProcessPropertyValues
    • 方法對屬性值進行修改(這個時候屬性值還未被設置,但是我們可以修改原本該設置進去的屬性值)。如果postProcessAfterInstantiation方法返回false,該方法不會被調用。可以在該方法內對屬性值進行修改
  • postProcessBeforeInitialization&postProcessAfterInitialization
    • 父接口BeanPostProcessor的2個方法

3. SmartInstantiationAwareBeanPostProcessor

智能實例化Bean后置處理器(繼承InstantiationAwareBeanPostProcessor)

  • determineCandidateConstructors
    • 檢測Bean的構造器,可以檢測出多個候選構造器(Java好像只會確定唯一的備選的構造器)
  • getEarlyBeanReference
    • 循環引用的后置處理器,這個東西比較復雜, 獲得提前暴露的bean引用。主要用于解決循環引用的問題,只有單例對象才會調用此方法
  • predictBeanType
    • 預測bean的類型,在最后的類型轉化時會用到

4. MergedBeanDefinitionPostProcessor

  • postProcessMergedBeanDefinition
    • 緩存bean的注入信息的后置處理器,僅僅是緩存或者干脆叫做查找更加合適,沒有完成注入,注入是另外一個后置處理器的作用(不實現這個方法,也能直接調用postProcessPropertyValues完成屬性值的注入)

5. DestructionAwareBeanPostProcessor

  • postProcessBeforeDestruction
    • 在bean實例被銷毀之前被調用

6.2 后置處理Bean的運行原理分析

在這里插入圖片描述

程序員實現BeanPostProcessor規定接口中的方法:

參數一:Spring工廠創建好的對象
參數二:對象名字
返回值:返回的對象會交給Spring框架
Object postProcessBeforeInitiallization(Object bean String beanName)
作用:Spring創建完對象,并進行注入后,會運行Before方法進行加工

Object postProcessAfterInitiallization(Object bean String beanName)
作用:Spring執行完對象的初始化操作后,會運行After方法進行加工

實戰中:
很少處理Spring的初始化操作:沒有必要區分Before After。只需要實現其中的一個After方法即可
注意:
postProcessBeforeInitiallization(){
return bean對象
}

6.3 BeanPostProcessor的開發步驟

1. 實現 BeanPostProcessor接口

public class MyBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {Categroy categroy = (Categroy) bean;categroy.setName("xiaowb");return categroy;}
}

2. Spring的配置文件中進行配置

<bean id="myBeanPostProcessor" class="xxx.MyBeanPostProcessor"/>

3. BeanPostProcessor細節

BeanPostProcessor會對Spring工廠中所有創建的對象進行加工。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/36499.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/36499.shtml
英文地址,請注明出處:http://en.pswp.cn/news/36499.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

創建型模式-原型模式

文章目錄 一、原型模式1. 概述2. 結構3. 實現4. 案例1.5 使用場景1.6 擴展&#xff08;深克隆&#xff09; 一、原型模式 1. 概述 用一個已經創建的實例作為原型&#xff0c;通過復制該原型對象來創建一個和原型對象相同的新對象。 2. 結構 原型模式包含如下角色&#xff1a; …

微服務架構和分布式架構的區別

微服務架構和分布式架構的區別 有&#xff1a;1、含義不同&#xff1b;2、概念層面不同&#xff1b;3、解決問題不同&#xff1b;4、部署方式不同&#xff1b;5、耦合度不同。其中&#xff0c;含義不同指微服務架構是一種將一個單一應用程序開發為一組小型服務的方法&#xff…

使用windows搭建WebDAV服務,并內網穿透公網訪問【無公網IP】

文章目錄 1. 安裝IIS必要WebDav組件2. 客戶端測試3. 使用cpolar內網穿透&#xff0c;將WebDav服務暴露在公網3.1 打開Web-UI管理界面3.2 創建隧道3.3 查看在線隧道列表3.4 瀏覽器訪問測試 4. 安裝Raidrive客戶端4.1 連接WebDav服務器4.2 連接成功4.2 連接成功 1. Linux(centos8…

【Vue-Router】路由入門

路由&#xff08;Routing&#xff09;是指確定網站或應用程序中特定頁面的方式。在Web開發中&#xff0c;路由用于根據URL的不同部分來確定應用程序中應該顯示哪個內容。 構建前端項目 npm init vuelatest //或者 npm init vitelatest安裝依賴和路由 npm install npm instal…

TCP重連 - 筆記

1 C++ TCP/IP 關于tcp斷線重連的問題 C++ TCP/IP 關于tcp斷線重連的問題_c++ 斷線重連_Bug&猿柒。的博客-CSDN博客 2 C++基礎--完善Socket C/S ,實現客戶端,服務器端斷開重連 https://www.cnblogs.com/kingdom_0/articles/2571727.html 3 C++實現Tcp通信(考慮客戶…

ATF BL1 UFS初始化簡單分析

ATF BL1 UFS初始化分析 1 ATF的下載鏈接2 ATF BL1 UFS 初始化簡易流程圖3 ATF BL1 ufs初始化簡單過程分析3.1 調用過程3.2 hikey960_ufs_init3.3 dw_ufs_init3.3 ufs_init 以海思hikey960為例來介紹&#xff0c;簡單介紹在ATF BL1階段的初始化處理。 1 ATF的下載鏈接 https:/…

藍帽杯 取證2022

網站取證 網站取證_1 下載附件 并解壓 得到了一個文件以及一個壓縮包 解壓壓縮包 用火絨查病毒 發現后門 打開文件路徑之后 發現了一句話木馬 解出flag 網站取證_2 讓找數據庫鏈接的明文密碼 打開www文件找找 查看數據庫配置文件/application/database.php&#xff08;CodeI…

Vue3.2+TS的父傳子,子傳父

這是父組件 <template><div><!-- 這個fn是子組件emit觸發名&#xff0c;兩邊保持一致 --><Child :num"num" fn"numUp"></Child></div> </template><script setup lang"ts"> import { ref } fr…

截止到目前全量主體總數有多少?

企業主體類型 企業主體類型有很多種&#xff0c;一般我們會分為公司&#xff08;有限責任&#xff09;、合伙企業、個人獨資企業、個體經營戶這些類別。 今天我們按照企業&#xff0c;個體&#xff0c;組織的分類方式來看各個主體的總數。 企業&#xff1a;統一社會信用代碼…

基于IP網絡的存儲協議——iSCSI

文章首發地址 iSCSI&#xff08;Internet Small Computer System Interface&#xff09;是一種基于IP網絡的存儲協議&#xff0c;它能夠在TCP/IP網絡上實現SCSI協議&#xff0c;使得不同的主機可以通過網絡共享存儲設備。iSCSI可以將存儲設備映射到本地主機上&#xff0c;使得主…

ARTS 挑戰打卡的第7天 --- Ubuntu中的WindTerm如何設置成中文,并且關閉shell中Tab鍵聲音(Tips)

前言 &#xff08;1&#xff09;Windterm是一個非常優秀的終端神器。關于他的下載我就不多說了&#xff0c;網上很多。今天我就分享一個國內目前沒有找到的這方面的資料——Ubuntu中的WindTerm如何設置成中文&#xff0c;并且關閉shell中Tab鍵聲音。 將WindTerm設置成中文 &…

【Mac】mac 系統下格式化U盤或移動硬盤為ext4格式

1. 打開終端&#xff0c;安裝 homebrew /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"2. 安裝之后再次運行此命令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"…

學習C++資料集合

學習C C 是一個難學易用的語言&#xff01; C 的難學&#xff0c;不僅在其廣博的語法&#xff0c;以及語法背後的語意&#xff0c;以及語意背後的深層思維&#xff0c;以及深層思維背後的物件模型&#xff1b; C 的難學&#xff0c;還在於它提供了四種不同&#xff08;但相輔相…

第五十三天

●剪輯——Pr 剪輯(Film editing)&#xff0c;即將影片制作中所拍攝的大量素材&#xff0c;經過選擇、取舍、分解與組接&#xff0c;最終完成一個連貫流暢、含義明確、主題鮮明并有藝術感染力的作品。 ?線性編輯 將素材按時間順序連接成新的連續畫面的技術 ?非線性編輯 …

Unity zSpace 開發

文章目錄 1.下載 zSpace 開發環境1.1 zCore Unity Package1.2 zView Unity Package 2. 導入工程3. 發布設置4.功能實現4.1 用觸控筆來實現對模型的拖拽&#xff1a; 5. 后續更新 1.下載 zSpace 開發環境 官網地址 1.1 zCore Unity Package zSpace 開發核心必須 1.2 zView …

MyBatis EntityWrapper DISTINCTQU用法

使用EntityWrapper進行DISTINCT查詢可以通過以下幾個步驟實現&#xff1a; 創建一個EntityWrapper對象&#xff1a;EntityWrapper<T> wrapper new EntityWrapper<>();使用setSqlSelect方法設置需要查詢的字段&#xff0c;并在字段前加上DISTINCT關鍵字&#xff0…

機器人CPP編程基礎-05完結The End

非常不可思議……之前四篇博文竟然有超過100的閱讀量…… 此文此部分終結&#xff0c;沒有繼續寫下去的必要了。 插入一個分享&#xff1a; 編程基礎不重要了&#xff0c;只要明確需求&#xff0c;借助AI工具就能完成一個項目。 當然也不是一次成功&#xff0c;工具使用也需要…

ORA-01539: 表空間 ‘GSC004‘ 未聯機

1.檢查表空間狀態&#xff1a; SELECT tablespace_name, status FROM dba_tablespaces WHERE tablespace_name GSC004;2.聯機表空間&#xff1a;如果表空間處于離線狀態&#xff0c;可以嘗試將其聯機。 ALTER TABLESPACE GSC004 ONLINE;3.檢查表空間文件&#xff0c;確保表空…

代碼隨想錄第48天 | 198. 打家劫舍、213. 打家劫舍II、337. 打家劫舍III

198. 打家劫舍 當前房屋偷與不偷取決于 前一個房屋和前兩個房屋是否被偷了。 遞歸五部曲&#xff1a; dp[i]&#xff1a;考慮下標i&#xff08;包括i&#xff09;以內的房屋&#xff0c;最多可以偷竊的金額為dp[i]。決定dp[i]的因素就是第i房間偷還是不偷。 如果偷第i房間&…

計算機視覺一 —— 介紹與環境安裝

傲不可長 欲不可縱 樂不可極 志不可滿 一、介紹 研究理論和應用 - 研究如何使機器“看”的科學 - 讓計算機具有人類視覺的所有功能 - 讓計算機從圖像中&#xff0c;提取有用的信息&#xff0c;并解釋 - 重構人眼&#xff1b;重構視覺皮層&#xff1b;重構大腦剩余部分 計…