欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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只有?個實例(單例)(默認 )
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ù)運行結(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進行管理):

@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默認的作用域,所有客戶端共享同一個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當中,多次請求,獲取的對象都是同一個。
但是我們換一個瀏覽器訪問會重新創(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對其進行了詳細的管理:

Bean的創(chuàng)建

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

依賴注入

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

初始化回調(diào)

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

Bean可用

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

銷毀回調(diào)

  • 當應(yīng)用上下文關(guān)閉時,調(diào)用Bean的銷毀方法。
  • @PreDestroy注解標注的方法,或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");
    }
}

啟動項目:

進行測試:

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

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

2. Spring Boot 自動配置流程

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

數(shù)據(jù)準備

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 標注的類 就是SpringBoot項目的啟動類。

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

解決方案

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

1. @ComponentScan 組件掃描

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

再進行測試:

獲取成功.

2. @Import

導(dǎo)入類

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

再進行測試:

獲取成功.

導(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);
	}
}

再進行測試:

獲取成功.

問題:
但是他們都有?個明顯的問題, 就是使用者需要知道第三方依賴中有哪些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);
	}
}

再進行測試:

獲取成功.

Spring boot 配置流程如下:

3.總結(jié)

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

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

相關(guān)文章

  • 一文詳解Java屬性為什么不能是is開頭的boolean

    一文詳解Java屬性為什么不能是is開頭的boolean

    在Java實體類定義中,boolean類型的屬性命名常引發(fā)爭議,阿里巴巴Java開發(fā)手冊建議避免使用is作為布爾類型屬性的前綴,原因在于當實體類被序列化或反序列化時,基于JavaBean規(guī)范的框架可能會移除或忽略is,導(dǎo)致不一致的字段名,文中介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • Java多線程之異步Future機制的原理和實現(xiàn)

    Java多線程之異步Future機制的原理和實現(xiàn)

    這篇文章主要為大家詳細介紹了Java多線程之異步Future機制的原理和實現(xiàn),感興趣的小伙伴們可以參考一下
    2016-08-08
  • Spring?Boot?3.1中整合Spring?Security和Keycloak的方法

    Spring?Boot?3.1中整合Spring?Security和Keycloak的方法

    本文介紹在最新的SpringBoot3.1版本之下,如何將Keycloak和Spring?Security一起跑起來,文中結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2023-06-06
  • Spring Boot 快速搭建微服務(wù)框架詳細教程

    Spring Boot 快速搭建微服務(wù)框架詳細教程

    SpringBoot是為了簡化Spring應(yīng)用的創(chuàng)建、運行、調(diào)試、部署等而出現(xiàn)的,使用它可以做到專注于Spring應(yīng)用的開發(fā),而無需過多關(guān)注XML的配置。本文重點給大家介紹Spring Boot 快速搭建微服務(wù)框架詳細教程,需要的的朋友參考下吧
    2017-09-09
  • shiro并發(fā)人數(shù)登錄控制的實現(xiàn)代碼

    shiro并發(fā)人數(shù)登錄控制的實現(xiàn)代碼

    在做項目中遇到這樣的需求要求每個賬戶同時只能有一個人登錄或幾個人同時登錄,如果是同時登錄的多人,要么不讓后者登錄,要么踢出前者登錄,怎么實現(xiàn)這樣的功能呢?下面小編給大家?guī)砹藄hiro并發(fā)人數(shù)登錄控制的實現(xiàn)代碼,一起看看吧
    2017-09-09
  • 解決springboot引入swagger2不生效問題

    解決springboot引入swagger2不生效問題

    這篇文章主要為大家介紹了解決springboot引入swagger2不生效問題的方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-05-05
  • 一文搞懂SpringMVC中@InitBinder注解的使用

    一文搞懂SpringMVC中@InitBinder注解的使用

    @InitBinder方法可以注冊控制器特定的java.bean.PropertyEditor或Spring Converter和 Formatter組件。本文通過示例為大家詳細講講@InitBinder注解的使用,需要的可以參考一下
    2022-06-06
  • SpringMVC注解@CrossOrigin跨域問題詳解

    SpringMVC注解@CrossOrigin跨域問題詳解

    這篇文章主要介紹了SpringMVC注解@CrossOrigin跨域問題詳解,跨域是瀏覽同源策略的造成,是瀏覽器對JavaScript施加的安全限制CORS是一種可以解決跨域問題的技術(shù),需要的朋友可以參考下
    2023-11-11
  • Java在PDF中添加表格過程詳解

    Java在PDF中添加表格過程詳解

    這篇文章主要介紹了Java在PDF中添加表格過程詳解,本文將介紹通過Java編程在PDF文檔中添加表格的方法。添加表格時,可設(shè)置表格邊框、單元格對齊方式、單元格背景色、單元格合并、插入圖片、設(shè)置行高、列寬、字體、字號等,需要的朋友可以參考下
    2019-07-07
  • servlet重定向詳解(八)

    servlet重定向詳解(八)

    這篇文章主要為大家詳細介紹了servlet重定向的相關(guān)資料,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-09-09

最新評論