【JavaEE進階】Bean 作用域和生命周期

文章目錄

  • 一. 關于Bean作用域的實例
    • 1. lombok
    • 2. 實例代碼
  • 二. 作用域定義
    • 1. Bean的六種作用域
    • 2. 設置作用域
  • 三. Spring 執行流程和 Bean 的生命周期
    • 1. Spring 執行流程
    • 2. Bean生命周期

一. 關于Bean作用域的實例

注意在此例子中需要用到lombok

1. lombok

lombok是什么?
Lombok 是一個 Java 庫,它通過注解的方式來簡化 Java 代碼的編寫。它提供了一組注解,讓我們可以通過在代碼中添加這些注解來自動生成樣板式的代碼,如 getter、setter、構造函數、toString 等。

使用 Lombok 可以有效地減少冗余的樣板代碼,提高代碼的可讀性和開發效率。不需要手動編寫大量的 getter 和 setter 方法,也不需要重復編寫 equals、hashCode 和 toString 方法等。通過簡單地添加幾個注解,Lombok 會在編譯時自動生成這些常見的方法和實現。

lombok的使用:

  1. 在框架中添加lombok依賴.
    在這里插入圖片描述
    在這里插入圖片描述
  2. 在實體類上使用lombok提供的注解.
    在這里插入圖片描述
  3. 安裝lombok插件在這里插入圖片描述

2. 實例代碼

Users:

package com.java.demo.enity;import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;@Controller
public class Users {@Beanpublic User user1(){User user = new User();user.setId(1);user.setName("xxxflower");return user;}
}

UserControlle:

package com.java.demo.controller;import com.java.demo.enity.User;
import org.springframework.stereotype.Controller;import javax.annotation.Resource;@Controller
public class UserController {@Resourceprivate User user1;public User UserPrint1() {User user = user1;System.out.println("Bean 原 Name:" + user.getName());user.setName("且聽風吟"); // 進?了修改操作System.out.println("UserController 修改后 Name: "+user.getName());return user;}
}

UserController2:

package com.java.demo.controller;import com.java.demo.enity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;@Controller
public class UserController2 {@Autowiredprivate User user1;public User UserPrint2() {User user = user1;System.out.println(user.toString());return user;}
}

App:

package com.java.demo;import com.java.demo.controller.UserController;
import com.java.demo.controller.UserController2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;@Controller
public class App {public static void main(String[] args) {ApplicationContext context =new ClassPathXmlApplicationContext("spring-config.xml");UserController userController = context.getBean("userController",UserController.class);System.out.println(userController.UserPrint1());UserController2 userController2 = context.getBean("userController2",UserController2.class);System.out.println(userController2.UserPrint2());}
}

代碼預計運行結果:
在這里插入圖片描述
代碼實際運行結果:
在這里插入圖片描述

我們可以看到上述第三行代碼和我們預計的結果不符,這是為什么呢?
以上問題的原因是Bean默認情況下采用的是單例狀態.(singleton),也就是所有的人使用的都是同一個Bean對象.在我們之前學習過的單例模式中,采用單例模式可以很大程度上提高性能,所以在Spring中Bean的作用域默認也是 singleton 單例模式.

二. 作用域定義

限定程序中變量的可?范圍叫做作?域,或者說在源代碼中定義變量的某個區域就叫做作?域。
Bean 的作用域是指 Bean 在 Spring 整個框架中的某種?為模式.比如 singleton 單例作?域,就表示 Bean 在整個 Spring 中只有?份,它是全局共享的,那么當其他?修改了這個值之后,那么另?個?讀取到的就是被修改的值。

1. Bean的六種作用域

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

  1. 單例模式: singleton(默認模式) -> 性能的考慮
  2. 原型模式: prototype
  3. 請求作用域:request,每次 HTTP請求,都會創建一個Bean對象。【適用于Spring MVC/Spring Web】
  4. 會話作用域:session,每次Session會話共享一個Bean。【Spring MVC】
  5. 全局作用域: application,一個http servlet context 中共享一個bean。【Spring MVC】
  6. webscoket: 網絡長連接,只適用于Spring WebSocket 項目。

注意后 4 種狀態是 Spring MVC 中的值,在普通的 Spring 項?中只有前兩種.

singleton

  • 官?說明:(Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
  • 描述:該作?域下的Bean在IoC容器中只存在?個實例:獲取Bean(即通過applicationContext.getBean等?法獲取)及裝配Bean(即通過@Autowired注?)都是同?個對 象。
  • 場景:通常?狀態的Bean使?該作?域。?狀態表示Bean對象的屬性狀態不需要更新 備注:Spring默認選擇該作?域

prototype

  • 官?說明:Scopes a single bean definition to any number of object instances.
  • 描述:每次對該作?域下的Bean的請求都會創建新的實例:獲取Bean(即通過applicationContext.getBean等?法獲取)及裝配 Bean(即通過@Autowired注?)都是新的對象實例。
  • 場景:通常有狀態的Bean使?該作?域

request

  • 官?說明:Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:每次http請求會創建新的Bean實例,類似于prototype
  • 場景:?次http的請求和響應的共享Bean
  • 備注:限定SpringMVC中使?

session

  • 官?說明:Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
  • 描述:在?個http session中,定義?個Bean實例
  • 場景:?戶回話的共享Bean, ?如:記錄?個?戶的登陸信息
  • 備注:限定SpringMVC中使?

2. 設置作用域

使? @Scope 標簽就可以?來聲明 Bean 的作?域,?如設置 Bean 的作?域,如下代碼所示:

package com.java.demo.enity;import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;@Controller
public class Users {//使用@Scope聲明Bean作用域@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)@Beanpublic User user1(){User user = new User();user.setId(1);user.setName("xxxflower");return user;}
}

運行結果:
在這里插入圖片描述
我們可以看到,在使用prototype時運行結果與預期結果相同.
關于@Scope的寫法有兩種:

  1. 直接設置值:@Scope("prototype")
  2. 使?枚舉設置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

三. Spring 執行流程和 Bean 的生命周期

1. Spring 執行流程

  1. 在main方法中遇到Application時啟動spring容器。
  2. 此時根據容器設置的配置文件去找相應配置文件。
  3. 如果存在basepackage 。此時去循環查看basepackage中是否有五大類注解。
  4. 如果有五大類注解,此時進行初始化和屬性依賴的賦值。
  5. 操作spring依賴 讀修改 書寫業務
  6. 關閉容器 釋放資源

圖解:
在這里插入圖片描述
Bean 執?流程(Spring 執?流程):啟動 Spring 容器 -> 實例化 Bean(分配內存空間,從?到
有) -> Bean 注冊到 Spring 中(存操作) -> 將 Bean 裝配到需要的類中(取操作)。

2. Bean生命周期

Bean 的生命周期是指一個 Bean 在被創建、初始化、使用和銷毀的整個過程。
Bean 生命周期(從誕生到銷毀過程):

  1. 開辟內存空間:實例化≠初始化
  2. 設置屬性(注入屬性)
  3. 初始化
    3.1 各種通知
    3.2 初始化前置方法
    3.3 初始化方法【兩種實現方式: xml 方式、注解方式】
    3.4 初始化后置方法
  4. 使用 Bean
  5. 銷毀Bean對象
    銷毀容器的各種?法,如 @PreDestroy、DisposableBean 接??法、destroy-method。

注意:一定是先設置屬性,再初始化.因為初始化的時候可能用到屬性的內容.

在這里插入圖片描述
生命周期演示:

首先,我們創建一個名為 ExampleBean 的 Java 類,實現了 Spring 的 InitializingBeanDisposableBean 接口,這兩個接口提供了在 Bean 初始化和銷毀時的回調方法。

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;public class ExampleBean implements InitializingBean, DisposableBean {public ExampleBean() {System.out.println("ExampleBean 構造函數");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("ExampleBean 初始化方法");}public void doSomething() {System.out.println("ExampleBean 執行業務邏輯");}@Overridepublic void destroy() throws Exception {System.out.println("ExampleBean 銷毀方法");}
}

然后,在 Spring 的配置文件中聲明該 Bean,并將其注入到其他類中使用:

<?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:content="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><content:component-scan base-package="com.java.demo"></content:component-scan><bean id="exampleBean" class="com.java.demo.ExampleBean" scope="singleton" init-method="afterPropertiesSet" destroy-method="destroy"/></beans>

在上述配置中,我們將 ExampleBean 聲明為一個 singleton 的 Bean,并指定了初始化方法為 afterPropertiesSet,銷毀方法為 destroy

接下來,我們創建一個簡單的測試類 ExampleApp 來使用 ExampleBean

package com.java.demo;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ExampleApp {public static void main(String[] args) {// 加載 Spring 的配置文件ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");// 獲取 ExampleBean 實例ExampleBean exampleBean =context.getBean("exampleBean",ExampleBean.class);// 執行業務邏輯exampleBean.doSomething();// 關閉 Spring 容器,觸發 Bean 的銷毀方法try {exampleBean.destroy();} catch (Exception e) {e.printStackTrace();}}
}

運行 ExampleApp 類,結果如下:

在這里插入圖片描述
需要注意的是,Bean 的生命周期可以進一步通過添加自定義的初始化和銷毀方法來擴展。可以使用 @PostConstruct @PreDestroy 注解,或者在 Spring 配置文件中通過 init-methoddestroy-method 屬性來指定自定義的初始化和銷毀方法。

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

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

相關文章

【C#】判斷打印機共享狀態

打印機共享狀態 /// <summary>/// 打印機共享狀態/// </summary>public enum PrinterShareState{/// <summary>/// 無打印機/// </summary>None -1,/// <summary>/// 未共享/// </summary>NotShare 0,/// <summary>/// 已共享/// …

soap通信2

首先&#xff0c;定義一個XSD&#xff08;XML Schema Definition&#xff09;來描述你的數據結構。在你的Maven項目的src/main/resources目錄下&#xff0c;創建一個名為schemas的文件夾&#xff0c;并在其中創建一個名為scriptService.xsd的文件&#xff0c;內容如下&#xff…

【kubernetes】調度約束

目錄 調度約束 Pod 啟動典型創建過程如下 調度過程 指定調度節點 查看詳細事件&#xff08;發現未經過 scheduler 調度分配&#xff09; 獲取標簽幫助 需要獲取 node 上的 NAME 名稱 給對應的 node 設置標簽分別為 ggls 和 gglm 查看標簽 修改成 nodeSelector 調度方…

vue學習筆記

1.官網 v2官網 https://v2.cn.vuejs.org/ v3官網 https://cn.vuejs.org/ 2.vue引入 在線引入 <script src"https://cdn.jsdelivr.net/npm/vue2.7.14/dist/vue.js"></script> 下載引入(下載鏈接) https://v2.cn.vuejs.org/js/vue.js 3.初始化渲…

Redis——通用命令介紹

Redis官方文檔 redis官方文檔 核心命令 set 將key和value存儲到Redis中&#xff0c;key和value都是字符串 set key valueRedis中不區分大小寫&#xff0c;字符串類型也不需要添加單引號或者雙引號 get 根據key讀取value&#xff0c;如果當前key不存在&#xff0c;則返回…

Offset Explorer

Offset Explorer 簡介下載安裝 簡介 Offset Explorer&#xff08;以前稱為Kafka Tool&#xff09;是一個用于管理和使Apache Kafka 集群的GUI應用程序。它提供了一個直觀的UI&#xff0c;允許人們快速查看Kafka集群中的對象以及存儲在集群主題中的消息。它包含面向開發人員和管…

RANSAC算法

RANSAC簡介 RANSAC(RAndom SAmple Consensus,隨機采樣一致)算法是從一組含有“外點”(outliers)的數據中正確估計數學模型參數的迭代算法。 “外點”一般指的的數據中的噪聲&#xff0c;比如說匹配中的誤匹配和估計曲線中的離群點。所以&#xff0c;RANSAC也是一種“外點”檢…

若依-plus-vue啟動顯示Redis連接錯誤

用的Redis是windows版本&#xff0c;6.2.6 報錯的主要信息如下&#xff1a; Failed to instantiate [org.redisson.api.RedissonClient]: Factory method redisson threw exception; nested exception is org.redisson.client.RedisConnectionException: Unable to connect t…

基于epoll的TCP服務器端(C++)

網絡編程——C實現socket通信(TCP)高并發之epoll模式_tcp通信c 多客戶端epoll_n大橘為重n的博客-CSDN博客 網絡編程——C實現socket通信(TCP)高并發之select模式_n大橘為重n的博客-CSDN博客 server.cpp #include <stdio.h> #include <sys/types.h> #include <…

Coin Change

一、題目 Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money. For example, if we have 11 cents, then we can make changes with one 10-cent coin and one 1-c…

springboot工程使用阿里云OSS傳輸文件

在application.yml文件中引入對應的配置&#xff0c;一個是對應的節點&#xff0c;兩個是密鑰和賬號&#xff0c;還有一個是對應文件的名稱&#xff1b; 采用這樣方式進行解耦&#xff0c;便于后期修改。 然后需要設置一個properties類&#xff0c;去讀對應的配置信息 用到了…

MySQL Linux自建環境備份至遠端服務器自定義保留天數

環境準備 linux下安裝mysql請看 Linux環境安裝單節點mysql8.0.16 系統版本: CentOS 7 軟件版本: mysql8.0.16 備份策略與實現方法 此次備份依賴mysql自帶命令mysqldump與linux下crontab命令(定時任務) mysqldump mysqldump客戶實用程序執行 邏輯備份,產生一組能夠被執行…

為什么需要知識圖譜,如何構建它?

從關系數據庫遷移到圖形數據庫的指南 跟隨 發表于 邁向數據科學 7 分鐘閱讀 4天前 154 4 一、說明 TLDR&#xff1a;知識圖譜在圖數據庫中組織事件、人員、資源和文檔&#xff0c;以進行高級分析。本文將解釋知識圖譜的用途&#xff0c;并向您展示如何將關系數據模型轉換為圖…

HTTP協議的發展過程

前言 HTTP協議是一種用于在網絡上傳輸信息的應用層協議&#xff0c;它為萬維網的運作提供了基礎。 最早的版本是HTTP/0.9&#xff0c;它是HTTP協議的第一個版本&#xff0c;誕生于1991年&#xff0c;其設計初衷是為了在計算機之間傳輸簡單的超文本文檔&#xff0c;即HTML。 在…

在Java中對XML的簡單應用

XML 數據傳輸格式1 XML 概述1.1 什么是 XML1.2 XML 與 HTML 的主要差異1.3 XML 不是對 HTML 的替代 2 XML 語法2.1 基本語法2.2 快速入門2.3 組成部分2.3.1 文檔聲明格式屬性 2.3.2 指令&#xff08;了解&#xff09;&#xff1a;結合CSS2.3.3 元素2.3.4 屬性**XML 元素 vs. 屬…

【Linux】Linux中獲取UUID的方法

1、從mmc塊設備獲取 在Linux下,獲取MMC的CID(Card Identification,識別ID) cat /sys/block/mmcblk0/device/cidMMC CID組成 MID: [127:120] —— 8bit(1Byte)Manufacturer ID,由MMCA分配,比如Sandisk為0x02,Kingston為0x37,Samsung為0x15。OID: [119:104] —— 16b…

windows程序基礎

一、windows程序基礎 1. Windows程序的特點 1&#xff09;用戶界面統一、友好 2&#xff09;支持多任務:允許用戶同時運行多個應用程序(窗口) 3&#xff09;獨立于設備的圖形操作 使用圖形設備接口( GDI, Graphics Device Interface )屏蔽了不同硬件設備的差異&#…

什么是視頻的編碼和解碼

這段描述中&#xff0c;視頻解碼能力和視頻編碼能力指的是不同的處理過程。視頻解碼是將壓縮過的視頻數據解開并還原為可播放的視頻流&#xff0c;而視頻編碼是將原始視頻數據壓縮成更小的尺寸&#xff0c;以減少存儲空間和傳輸帶寬。在這個上下文中&#xff0c;解碼能力和編碼…

LVGL學習筆記 30 - List(列表)

目錄 1. 添加文本 2. 添加按鈕 3. 事件 4. 修改樣式 4.1 背景色 4.2 改變項的顏色 列表是一個垂直布局的矩形&#xff0c;可以向其中添加按鈕和文本。 lv_obj_t* list1 lv_list_create(lv_scr_act());lv_obj_set_size(list1, 180, 220);lv_obj_center(list1); 部件包含&…

Android:換膚框架Android-Skin-Support

gihub地址&#xff1a;https://github.com/ximsfei/Android-skin-support 樣例&#xff1a; 默認&#xff1a; 更換后&#xff1a; 一、引入依賴&#xff1a; // -- 換膚依賴implementation skin.support:skin-support:4.0.5// skin-supportimplementation skin.support:ski…