亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java開發(fā)學(xué)習(xí)之Bean的作用域和生命周期詳解

 更新時(shí)間:2022年06月17日 08:54:49   作者:富春山居_ZYY  
這篇文章主要介紹了淺談Spring中Bean的作用域,生命周期和注解,從創(chuàng)建到消亡的完整過程,例如人從出生到死亡的整個(gè)過程就是一個(gè)生命周期。本文將通過示例為大家詳細(xì)講講,感興趣的可以學(xué)習(xí)一下

一、Bean 的作用域

在之前學(xué)習(xí)Java基礎(chǔ)的時(shí)候,有接觸到作用域這樣的概念。一個(gè)變量并不一定在任何區(qū)域都是有效的,限定這個(gè)變量的可用性的代碼范圍就是該變量的作用域。

但是在這里 Bean 的作用域的概念和以前所認(rèn)為的作用域有所不同。

Bean 的作用域是指 Bean 在 Spring 整個(gè)框架中的某種行為模式。

接下來,將會(huì)舉一個(gè)案例來講講什么是作用域,什么是行為模式

案例概要:

創(chuàng)建一個(gè)共有的 Bean ,使用者A和使用者B都對(duì)該 Bean 進(jìn)行了使用

使用者A在進(jìn)行使用的時(shí)候,創(chuàng)建一個(gè)新的變量接收注入進(jìn)來的 Bean,進(jìn)行修改,將修改后的結(jié)果進(jìn)行返回;

使用者B 直接將注入進(jìn)來的 Bean 進(jìn)行返回,不進(jìn)行任何操作

代碼實(shí)現(xiàn):

步驟一:創(chuàng)建出一個(gè)公共的 Bean

@Component
public class UserComponent {
    @Bean
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("張三");
        user.setPassWord("111111");
        return user;
    }
}

步驟二:使用者A獲取到公共 Bean,進(jìn)行修改

@Controller
public class UserControllerA {
    @Autowired
    private User user;
    public User getUser1() {
        System.out.println("使用者A拿到的原始user:" + user);
        User myUser = user;
        myUser.setName("李四");
        return myUser;
    }
}

步驟三:使用者B直接將獲取到的公共的 Bean 進(jìn)行返回

@Controller
public class UserControllerB {
    @Autowired
    private User user;
    public User getUser2() {
        return user;
    }
}

步驟四:main 中獲取 UserControllerA 類和 UserControllerB 類使用查看

public class Start {
    public static void main(String[] args) {
        //獲取 Spring 上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        //獲取到Spring容器中的 UserControllerA 類(Bean 對(duì)象)
        UserControllerA userControllerA = context.getBean("userControllerA",UserControllerA.class);
        //使用 Bean 對(duì)象
        System.out.println("使用者A->"+userControllerA.getUser1());
		//獲取到Spring容器中的 UserControllerA 類(Bean 對(duì)象)
        UserControllerB userControllerB = context.getBean("userControllerB",UserControllerB.class);
        //使用 Bean 對(duì)象
        System.out.println("使用者B->"+userControllerB.getUser2());
    }
}

預(yù)期結(jié)果:

使用者 A修改后,其結(jié)果是修改過的;使用者 B 沒有修改過,其結(jié)果應(yīng)該和原始user一樣

結(jié)果顯示:

和預(yù)期結(jié)果有所不同,使用者 A 和使用者 B 所得到的結(jié)果都是被修改過的。

這是因?yàn)樵?Spring 中,Bean 默認(rèn)情況下是單例狀態(tài),大家用的都是同一份對(duì)象,是全局共享的,當(dāng)有其他人修改了該對(duì)象,另一個(gè)人所獲取到的對(duì)象就是被修改過的,這便是 Bean 六大作用域之一——單例作用域(singleton)

在寫 WEB 項(xiàng)目的時(shí)候,我們知道 DataSource 就是單例模式,使用單例,好處多多,可以確保所有對(duì)象都訪問唯一實(shí)例,而且減少了內(nèi)存的開支和系統(tǒng)性能的開銷,因此 Bean 默認(rèn)情況下是單例狀態(tài)。

若想要按照預(yù)期結(jié)果輸出,就需要將 Bean 的作用域設(shè)置成原型作用域,即無論誰來使用 Bean 對(duì)象,獲取到的都是原始的 Bean 對(duì)象,大家各玩各的。

需要在注入的對(duì)象上使用注解修改作用域,有以下兩種方法(Scope就是作用域的意思)

  • 直接將作用域以 String 類型寫到()中
  • 使用全局參數(shù),類似于枚舉
@Component
public class UserComponent {
    //@Scope("prototype")    //方法一
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) //方法二
    @Bean
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("張三");
        user.setPassWord("111111");
        return user;
    }
}

Bean 的 6 種作用域

singleton:?jiǎn)卫饔糜?

  • Bean 在 IoC 容器中只存在一個(gè)實(shí)例
  • 當(dāng) Bean 對(duì)象屬性狀態(tài)無需更新時(shí)使用該作用域
  • Spring 支持

prototype:原型作?域/多例作?域

  • 每次獲取該 Bean 時(shí)都會(huì)創(chuàng)建新的實(shí)例,即獲取的都是原始的 Bean
  • 當(dāng) Bean 對(duì)象屬性狀態(tài)會(huì)更新時(shí)使用該作用域
  • Spring 支持

request:請(qǐng)求作用域

  • 每次 HTTP 請(qǐng)求都會(huì)創(chuàng)建新的 Bean 實(shí)例
  • 一次 HTTP 請(qǐng)求和響應(yīng)共享的 Bean
  • 限定 SpringMVC

session:會(huì)話作用域

  • 在一個(gè) HTTP session中,創(chuàng)建一個(gè) Bean 實(shí)例
  • 用戶會(huì)話共享一個(gè) Bean
  • 限定 SpringMVC

application:全局作用域

  • 在一個(gè) HTTP Servlet Context中,創(chuàng)建一個(gè) Bean 實(shí)例
  • 一個(gè) WEB 上下文中共享一個(gè) Bean
  • 限定 SpringMVC

websocket: HTTP WebSocket 作?域(不常用)

  • 在一個(gè) HTTP WebSocket 中,創(chuàng)建一個(gè) Bean 實(shí)例
  • 限定 Spring WebSocket

單例作用域和全局作用域比較像,但全局作用域范圍沒有單例作用域大,前者是 Spring 核心的作用域,后者是 Spring Web 中的作用域,前者作用于 IoC 容器,后者作用于 Servlet 容器

二、Spring 的執(zhí)行流程

Spring 的執(zhí)行流程也可以說是 Bean的執(zhí)行流程,主要分成4部分

  • 啟動(dòng) Spring 容器
  • 加載 XML 文件,實(shí)例化 Bean(進(jìn)行內(nèi)存的分配)
  • Bean 存到 Spring 容器中(五大類注解,方法注解)
  • 將存儲(chǔ)的 Bean 中的注入的對(duì)象屬性進(jìn)行初始化,即進(jìn)行裝配(取出 Bean)

三、Bean 的生命周期

Bean 的生命周期即 Bean 從誕生到銷毀的整個(gè)過程

實(shí)例化 Bean 對(duì)象,申請(qǐng)內(nèi)存空間

設(shè)置 Bean 的屬性,進(jìn)行依賴注入和裝配

Bean 的初始化

  • 各種 Aware 感知:BeanNameAware、BeanFactoryAware、ApplicationContextAware、…
  • 執(zhí)? BeanPostProcessor 初始化前置?法
  • 初始化方法:構(gòu)造器方法 @PostConstructor (對(duì)象加載完依賴注入后執(zhí)行)
  • 初始化方法:init-method
  • 執(zhí)? BeanPostProcessor 初始化后置?法

使用 Bean

銷毀 Bean

  • 銷毀方法:@PreDestroy
  • 接口方法:DisposableBean
  • 銷毀方法:destroy-method

補(bǔ)充

實(shí)例化和初始化的區(qū)別

  • 實(shí)例化:這里的實(shí)例化和從前的實(shí)例化對(duì)象是有區(qū)別的,這里的實(shí)例化就負(fù)責(zé)內(nèi)存的分配,一個(gè)從無到有的過程。實(shí)例化和屬性設(shè)置時(shí) Java 級(jí)別的系統(tǒng)“事件”,操作過程是不可人工干預(yù)的
  • 初始化:是對(duì) Bean 進(jìn)行填充的過程,程序員可以進(jìn)行介入,真正的將 Bean 放到 Spring 容器中

@PostConstructor 和 @PreDestroy 是注解方式進(jìn)行初始化和注銷,init-method 和 destroy-method 是 XML 方法進(jìn)行初始化和注銷,一般只要使用其中的一種進(jìn)行初始化

設(shè)置屬性一定要在初始化之前,因?yàn)槌跏蓟部赡苄枰褂玫阶⑷氲膶?duì)象,如果沒有進(jìn)行屬性的設(shè)置,初始化就會(huì)出現(xiàn)問題

案例:生命周期演示

@Component
public class BeanLife implements BeanNameAware {
    @Override
    public void setBeanName(String s) {
        System.out.println("BeanName 感知:"+ s);
    }
    @PostConstruct
    public void postConstructor() {
        System.out.println("執(zhí)行初始化方法:PostConstructor");
    }
    @PreDestroy
    public void preDestroy() {
        System.out.println("執(zhí)行銷毀方法:PreDestroy");
    }
    public void initMethod() {
        System.out.println("執(zhí)行初始化方法:init-method");
    }
    public void destroyMethod() {
        System.out.println("執(zhí)行銷毀方法:destroy-method");
    }
}

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: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">
    <!-- 配置一下:bean注解掃描的根路徑(方面后面更簡(jiǎn)單存儲(chǔ)對(duì)象到spring容器)-->
    <content:component-scan base-package="com.bit.beans"></content:component-scan>
    <beans>
        <bean id="beanLife" class="com.bit.beans.Component.BeanLife" init-method="initMethod"
        destroy-method="destroyMethod"></bean>
    </beans>
</beans>

調(diào)用

public class Start {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new
                ClassPathXmlApplicationContext("spring.xml");
        BeanLife beanLife = context.getBean("beanLife",BeanLife.class);
        System.out.println("---使用 Bean 對(duì)象---");
        System.out.println("---注銷 Bean 對(duì)象--- ");
        context.destroy();//容器的銷毀相當(dāng)于銷毀所有的 Bean
    }
}

結(jié)果顯示:

流程圖展示:

到此這篇關(guān)于Java開發(fā)學(xué)習(xí)之Bean的作用域和生命周期詳解的文章就介紹到這了,更多相關(guān)Bean作用域和生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐

    Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐

    最近的一個(gè)項(xiàng)目中涉及到了支付業(yè)務(wù),其中用到了微信支付和支付寶支付,本文就來介紹一下Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-10-10
  • Java SSM框架如何添加寫日志功能

    Java SSM框架如何添加寫日志功能

    這篇文章主要介紹了Java SSM框架如何添加寫日志功能,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-09-09
  • Java深入講解SPI的使用

    Java深入講解SPI的使用

    SPI英文全稱為Service Provider Interface,顧名思義,服務(wù)提供者接口,它是jdk提供給“服務(wù)提供廠商”或者“插件開發(fā)者”使用的接口
    2022-06-06
  • SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口

    SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口

    接口限流是為了保護(hù)系統(tǒng)和服務(wù),防止因?yàn)檫^多的請(qǐng)求而崩潰,本文主要介紹了SpringCloud+Redis實(shí)現(xiàn)Api接口限流防止惡意刷接口,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-03-03
  • Spring?Boot整合ELK實(shí)現(xiàn)日志采集與監(jiān)控

    Spring?Boot整合ELK實(shí)現(xiàn)日志采集與監(jiān)控

    這篇文章主要介紹了Spring?Boot整合ELK實(shí)現(xiàn)日志采集與監(jiān)控,需要的朋友可以參考下
    2022-06-06
  • Java內(nèi)部排序之插入排序與交換排序詳解

    Java內(nèi)部排序之插入排序與交換排序詳解

    這篇文章主要介紹了Java內(nèi)部排序之插入排序與交換排序詳解,排序是將任意序列重新排列按照關(guān)鍵字有序,排序根基存儲(chǔ)器的不同分為內(nèi)部排序、外部排序,排序根據(jù)關(guān)鍵字分為穩(wěn)定排序、不穩(wěn)定排序,需要的朋友可以參考下
    2023-12-12
  • Java數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)哈希表的分離鏈接法

    Java數(shù)據(jù)結(jié)構(gòu)之實(shí)現(xiàn)哈希表的分離鏈接法

    今天給大家?guī)淼氖顷P(guān)于Java數(shù)據(jù)結(jié)構(gòu)的相關(guān)知識(shí),文章圍繞著Java哈希表的分離鏈接法展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Java 中的io模型詳解

    Java 中的io模型詳解

    這篇文章主要介紹了Java 中io模型的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下
    2021-04-04
  • Spring中@Value注解的使用方法詳解

    Spring中@Value注解的使用方法詳解

    這篇文章主要介紹了Spring中@Value注解的使用方法詳解,在spring項(xiàng)目中必不可少的就是讀取配置文件,那么讀取配置文件就有兩種方式,一種就是使用Spring中@Value注解,還有一種是使用SpringBoot中的@ConfigurationProperties注解,需要的朋友可以參考下
    2024-01-01
  • mybatis plus 的動(dòng)態(tài)表名的配置詳解

    mybatis plus 的動(dòng)態(tài)表名的配置詳解

    這篇文章主要介紹了mybatis plus 的動(dòng)態(tài)表名的配置詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09

最新評(píng)論