最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBean管理與Spring Boot自動配置原理解析

 更新時間:2025年05月28日 15:17:17   作者:權(quán)^  
在Spring中,Bean的作用域(Scope)決定了Bean的實例化方式以及其生命周期,下面給大家介紹SpringBean管理與Spring Boot自動配置原理解析,感興趣的朋友一起看看吧

Spring 原理深入探索

1. Bean 的作用域和生命周期

1.1 Bean 的作用域

在Spring中,Bean的作用域(Scope)決定了Bean的實例化方式以及其生命周期。以下是Spring中常見的Bean作用域:

作用域說明
singleton每個Spring IoC容器內(nèi)同名稱的bean只有?個實例(單例)(默認(rèn) )
prototype每次使用該bean時會創(chuàng)建新的實例(非單例)
request每個HTTP 請求生命周期內(nèi), 創(chuàng)建新的實例
session每個HTTP Session生命周期內(nèi), 創(chuàng)建新的實例
application每個ServletContext生命周期內(nèi), 創(chuàng)建新的實例
websocket每個WebSocket生命周期內(nèi), 創(chuàng)建新的實例

我們直接上代碼 后面根據(jù)運(yùn)行結(jié)果觀察Bean的作用域。

創(chuàng)建一個Dog實體類:

public class Dog {
    private  String name;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

創(chuàng)建一個DogCompoent類(交給Spring進(jìn)行管理):

@Component
public class DogCompoent {
    @Bean
    public Dog dog(){
        return new Dog();
    }
//    單例
    @Bean
    public Dog singleDog(){
        return new Dog();
    }
//    多例
    @Bean
    @Scope("prototype")
    public Dog prototypeDog(){
        return new Dog();
    }
//request
    @Bean
    @RequestScope
    public Dog requestDog(){
        return new Dog();
    }
 //session
    @Bean
    @SessionScope
    public Dog sessionDog(){
        return new Dog();
    }
    //application
    @Bean
    @ApplicationScope
    public Dog applicationDog(){
        return new Dog();
    }
}

定義一個controller類:

@RestController
@RequestMapping("/dog")
public class DogController {
    @Autowired
    ApplicationContext context;
      //  單例作用域
    @Resource(name = "singleDog")
    Dog singleDog;
    //    多例作用域(原型)
    @Resource(name="prototypeDog")
    Dog prototypeDog;
//
    @Resource(name = "requestDog")
    Dog requestDog;
//
    @Resource(name = "sessionDog")
    Dog sessionDog;
//
    @Resource(name = "applicationDog")
    Dog applicationDog;
    @RequestMapping("/singleton")
    public String singleton(){
        Dog contextDog = context.getBean("singleDog", Dog.class);
        return "contextDog"+contextDog+",resource"+singleDog;
    }
    @RequestMapping("/prototype")
    public String prototype(){
        Dog contextDog = context.getBean("prototypeDog", Dog.class);
        return "contextDog"+contextDog+",resource"+prototypeDog;
    }
    @RequestMapping("/request")
    public String  request(){
        Dog contextDog = context.getBean("requestDog", Dog.class);
        return "contextDog"+contextDog+",resource"+ requestDog;
    }
    @RequestMapping("/session")
    public String session(){
        Dog contextDog = context.getBean("sessionDog", Dog.class);
        return "contextDog"+contextDog+",resource"+ sessionDog;
    }
    @RequestMapping("/application")
    public String application(){
        Dog contextDog = context.getBean("applicationDog", Dog.class);
        return "contextDog"+contextDog+",resource"+ applicationDog;
    }
}

啟動類:

@SpringBootApplication
public class SpringPrincipleApplication {
	public static void main(String[] args) {
SpringApplication.run(SpringPrincipleApplication.class, args);
	}
}

啟動項目: 測試不同作用域的Bean取到的對象是否一樣:

  • Singleton(單例)
    • Spring默認(rèn)的作用域,所有客戶端共享同一個Bean實例。
    • 適用于無狀態(tài)Bean。

單例作用域的Bean:http://127.0.0.1:8080:/dog/singleton

多次訪問, 得到的都是同?個對象, 并且 @Autowired 和applicationContext.getBean()也是同?個對象。

  • Prototype(原型)
    • 每次注入或獲取Bean時,都會創(chuàng)建一個新的實例。
    • 適用于有狀態(tài)Bean。

原型作用域的Bean:http://127.0.0.1:8080:/dog/prototype

觀察ContextDog, 每次獲取的對象都不?樣(注入的對象在Spring容器啟動時, 就已經(jīng)注入了, 所以多次請求也不會發(fā)生變化)

  • Request(請求范圍)
    • 每個HTTP請求創(chuàng)建一個新的Bean實例。
    • 適用于Web應(yīng)用中的請求相關(guān)數(shù)據(jù)。
    • request作用域的Bean:http://127.0.0.1:8080:/dog/request

在?次請求中, @Autowired 和 applicationContext.getBean() 也是同?個對象.但是每次請求, 都會重新創(chuàng)建對象.

  • Session(會話范圍)
    • 每個HTTP會話創(chuàng)建一個新的Bean實例。
    • 適用于用戶會話相關(guān)數(shù)據(jù)。

session作用域的Bean:http://127.0.0.1:8080:/dog/session

在一個session當(dāng)中,多次請求,獲取的對象都是同一個。
但是我們換一個瀏覽器訪問會重新創(chuàng)建對象(另外一個session)

  • Application(應(yīng)用范圍)
    • 每個ServletContext創(chuàng)建一個Bean實例。

session作用域的Bean:http://127.0.0.1:8080:/dog/application

在?個應(yīng)用中, 多次訪問都是同一個對象.
Application scope就是對于整個web容器來說, bean的作?域是ServletContext級別的. 這個和
singleton有點類似,區(qū)別在于: Application scope是ServletContext的單例, singleton是?個
ApplicationContext的單例. 在?個web容器中ApplicationContext可以有多個。

1.2 Bean 的生命周期

Bean的生命周期從創(chuàng)建到銷毀,Spring對其進(jìn)行了詳細(xì)的管理:

Bean的創(chuàng)建

  • 通過構(gòu)造器或工廠方法創(chuàng)建Bean實例。

依賴注入

  • 根據(jù)配置注入Bean的依賴項。

初始化回調(diào)

  • 調(diào)用Bean的初始化方法(如@PostConstruct注解標(biāo)注的方法)。
  • Spring的InitializingBean接口或自定義初始化方法。

Bean可用

  • Bean已經(jīng)準(zhǔn)備就緒,可以被應(yīng)用程序使用。

銷毀回調(diào)

  • 當(dāng)應(yīng)用上下文關(guān)閉時,調(diào)用Bean的銷毀方法。
  • @PreDestroy注解標(biāo)注的方法,或DisposableBean接口。

創(chuàng)建一個BeanLifeComponent類繼承BeanNameAware來說明Bean的生命周期從創(chuàng)建到銷毀。

代碼:

import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class BeanLifeComponent implements BeanNameAware {
//
//    @Autowired
    private DogCompoent dogCompoent;
    //1. 實例化
    public BeanLifeComponent() {
        System.out.println("執(zhí)行構(gòu)造方法....");
    }
 //    2.屬性賦值(seter方法注入)
@Autowired
    public void setDogCompoent(DogCompoent dogCompoent) {
        this.dogCompoent = dogCompoent;
    System.out.println("執(zhí)行屬性賦值");
}
//獲取Bean的名稱
    @Override
    public void setBeanName(String name) {
        System.out.println("執(zhí)行BeanNameAware,beanName:"+name);
    }
//    初始化方法
    @PostConstruct
    public void init(){
        System.out.println("初始化方法...");
    }
//    4.使用Bean
    public void use(){
        System.out.println("使用Bean,執(zhí)行use 方法");
    }
    //    5.銷毀Bean
    @PreDestroy
    public void destroy(){
        System.out.println("銷毀bean");
    }
}

啟動項目:

進(jìn)行測試:

@Test
	void testBean(){
		BeanLifeComponent bean = context.getBean(BeanLifeComponent.class);
		bean.use();
	}

可以看到使用Bean成功了。
流程:

2. Spring Boot 自動配置流程

SpringBoot的自動配置就是當(dāng)Spring容器啟動后, ?些配置類, bean對象等就自動存入到了IoC容器中,不需要我們手動去聲明, 從而簡化了開發(fā), 省去了繁瑣的配置操作。
SpringBoot自動配置, 就是指SpringBoot是如何將依賴jar包中的配置類以及Bean加載到Spring IoC容器中的Spring Boot通過自動配置(Auto-Configuration)簡化了配置過程,以下是其核心流程:

數(shù)據(jù)準(zhǔn)備

import org.springframework.context.annotation.Configuration;
//第三方
@Configuration
public class Sliqverconfig {
    public void study(){
        System.out.println("Sliqverconfig study... ");
    }
}

獲取Sliqverconfig這個Bean
寫測試用例:

@Autowired
 ApplicationContext context;
	@Test
	void testBean(){
		Sliqverconfig bean = context.getBean(Sliqverconfig.class);
		System.out.println(bean);
	}

可以看到測試報錯,那這個是什么原因呢?

原因分析

Spring通過五?注解和 @Bean 注解可以幫助我們把Bean加載到SpringIoC容器中, 以上有個前提就是這些注解類需要和SpringBoot啟動類在同?個目錄下 ( @SpringBootApplication 標(biāo)注的類 就是SpringBoot項目的啟動類。

可以看到這個Sliqverconfig類并不和啟動類在同一個包下面。
這個Sliqverconfig類相當(dāng)于第三方包,那我們怎么樣把這個包,交給Spring管理這些Bean呢?

解決方案

我們需要指定路徑或者引入的文件, 告訴Spring, 讓Spring進(jìn)行掃描到.
常見的解決方法有兩種:

1. @ComponentScan 組件掃描

@ComponentScan(basePackages = "com.config")
@SpringBootApplication
public class SpringPrincipleApplication {
	public static void main(String[] args) {
SpringApplication.run(SpringPrincipleApplication.class, args);
	}
}

再進(jìn)行測試:

獲取成功.

2. @Import

導(dǎo)入類

@Import(Sliqverconfig.class)
@SpringBootApplication
public class SpringPrincipleApplication {
	public static void main(String[] args) {
SpringApplication.run(SpringPrincipleApplication.class, args);
	}
}

再進(jìn)行測試:

獲取成功.

導(dǎo)? ImportSelector 接口實現(xiàn)類

public class MySelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{"com.config.Sliqverconfig"};
    }
}

啟動類:

@Import(MyRegistrar.class)
@SpringBootApplication
public class SpringPrincipleApplication {
	public static void main(String[] args) {
SpringApplication.run(SpringPrincipleApplication.class, args);
	}
}

再進(jìn)行測試:

獲取成功.

問題:
但是他們都有?個明顯的問題, 就是使用者需要知道第三方依賴中有哪些Bean對象或配置類. 如果漏掉其中?些Bean, 很可能導(dǎo)致我們的項目出現(xiàn)大的事故.這對程序員來說非常不友好.
依賴中有哪些Bean, 使用時候需要配置哪些bean, 第三方依賴最清楚, 那能否由第三方依賴來做這件事呢?
比較常見的方法就是第三方依賴給我們提供?個注解, 這個注解?般都以@EnableXxxx開頭的注解,注解中封裝的就是 @Import 注解.

第三?依賴提供注解.

import org.springframework.context.annotation.Import;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//注解
//類
@Target(ElementType.TYPE)
//生命周期
@Retention(RetentionPolicy.RUNTIME)
@Import(MySelector.class)//指定要導(dǎo)入的類
public @interface EnableSliqversConfig {
}

注解中封裝 @Import 注解, 導(dǎo)入MySelector.class

啟動類:
直接使用第三方提供的注解:

//通過第三方注解 @EnableSliqversConfig
@EnableSliqversConfig
@SpringBootApplication
public class SpringPrincipleApplication {
	public static void main(String[] args) {
SpringApplication.run(SpringPrincipleApplication.class, args);
	}
}

再進(jìn)行測試:

獲取成功.

Spring boot 配置流程如下:

3.總結(jié)

Spring的Bean管理和生命周期機(jī)制是其核心功能,而Spring Boot的自動配置流程則大大簡化了配置工作,幫助開發(fā)者快速構(gòu)建應(yīng)用。

到此這篇關(guān)于SpringBean管理與Spring Boot自動配置原理解析的文章就介紹到這了,更多相關(guān)Spring Boot自動配置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • kafka的消息存儲機(jī)制和原理分析

    kafka的消息存儲機(jī)制和原理分析

    這篇文章主要介紹了kafka的消息存儲機(jī)制和原理,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • Java 替換字符串中的回車換行符的方法

    Java 替換字符串中的回車換行符的方法

    Java 替換字符串中的回車換行符的方法,需要的朋友可以參考一下
    2013-03-03
  • lombok @Accessors用法詳解

    lombok @Accessors用法詳解

    這篇文章主要介紹了lombok @Accessors用法詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11
  • Java Structs框架原理案例詳解

    Java Structs框架原理案例詳解

    這篇文章主要介紹了Java Structs框架原理案例詳解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • Java8 HashMap鍵與Comparable接口小結(jié)

    Java8 HashMap鍵與Comparable接口小結(jié)

    這篇文章主要介紹了Java8 HashMap鍵與Comparable接口小結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Java利用future及時獲取多線程運(yùn)行結(jié)果

    Java利用future及時獲取多線程運(yùn)行結(jié)果

    在Java編程中,有時候會需要及時獲取線程的運(yùn)行結(jié)果,本文就通過一個相關(guān)實例向大家介紹Java利用future及時獲取線程運(yùn)行結(jié)果的方法,需要的朋友可以參考。
    2017-10-10
  • 深入探究MyBatis插件機(jī)制靈活擴(kuò)展及自定義增強(qiáng)框架能力

    深入探究MyBatis插件機(jī)制靈活擴(kuò)展及自定義增強(qiáng)框架能力

    這篇文章主要介紹了深入探究MyBatis插件機(jī)制靈活擴(kuò)展及自定義增強(qiáng)框架能力
    2024-01-01
  • SpringBoot整合Jackson超詳細(xì)用法(附Jackson工具類)

    SpringBoot整合Jackson超詳細(xì)用法(附Jackson工具類)

    這篇文章主要介紹了SpringBoot整合Jackson超詳細(xì)教程,本篇講的是Jackson的詳細(xì)用法,Jackson工具類在文章最后,直接復(fù)制粘貼即可使用,需要的朋友可以參考下
    2023-03-03
  • Java 8中如何獲取參數(shù)名稱的方法示例

    Java 8中如何獲取參數(shù)名稱的方法示例

    這篇文章主要給大家介紹了在Java 8中如何獲取參數(shù)名稱的方法,文中給出了詳細(xì)的介紹和方法示例,相信對大家的理解和學(xué)習(xí)具有一定的參考借鑒價值,有需要的朋友可以參考學(xué)習(xí),下面來一起看看吧。
    2017-01-01
  • 基于@RequestMapping 用法詳解之地址映射

    基于@RequestMapping 用法詳解之地址映射

    這篇文章主要介紹了@RequestMapping 用法詳解之地址映射,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08

最新評論

庆元县| 鄂温| 吐鲁番市| 吉安市| 筠连县| 紫阳县| 白城市| 淮滨县| 神池县| 拉孜县| 天门市| 加查县| 多伦县| 新建县| 南漳县| 德令哈市| 大荔县| 盐边县| 平定县| 江西省| 鲁甸县| 青神县| 岚皋县| 无极县| 长岭县| 文水县| 海林市| 静乐县| 肥乡县| 财经| 洛扎县| 阳朔县| 临沂市| 平潭县| 宁德市| 赣榆县| 侯马市| 毕节市| 五河县| 剑阁县| 星座|