国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用

這篇具有很好參考價(jià)值的文章主要介紹了Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

1. Spring的內(nèi)置作用域

我們來看看Spring內(nèi)置的作用域類型。在5.x版本中,Spring內(nèi)置了六種作用域:

  • singleton:在IOC容器中,對應(yīng)的Bean只有一個實(shí)例,所有對它的引用都指向同一個對象。這種作用域非常適合對于無狀態(tài)的Bean,比如工具類或服務(wù)類。
  • prototype:每次請求都會創(chuàng)建一個新的Bean實(shí)例,適合對于需要維護(hù)狀態(tài)的Bean。
  • request:在Web應(yīng)用中,為每個HTTP請求創(chuàng)建一個Bean實(shí)例。適合在一個請求中需要維護(hù)狀態(tài)的場景,如跟蹤用戶行為信息。
  • session:在Web應(yīng)用中,為每個HTTP會話創(chuàng)建一個Bean實(shí)例。適合需要在多個請求之間維護(hù)狀態(tài)的場景,如用戶會話。
  • application:在整個Web應(yīng)用期間,創(chuàng)建一個Bean實(shí)例。適合存儲全局的配置數(shù)據(jù)等。
  • websocket:在每個WebSocket會話中創(chuàng)建一個Bean實(shí)例。適合WebSocket通信場景。

我們需要重點(diǎn)學(xué)習(xí)兩種作用域:singletonprototype。在大多數(shù)情況下singletonprototype這兩種作用域已經(jīng)足夠滿足需求。


2. singleton作用域

2.1 singleton作用域的定義和用途

??SingletonSpring的默認(rèn)作用域。在這個作用域中,Spring容器只會創(chuàng)建一個實(shí)例,所有對該bean的請求都將返回這個唯一的實(shí)例。

例如,我們定義一個名為Plaything的類,并將其作為一個bean

@Component
public class Plaything {

    public Plaything() {
        System.out.println("Plaything constructor run ...");
    }
}

??在這個例子中,Plaything是一個singleton作用域的bean。無論我們在應(yīng)用中的哪個地方請求這個bean,Spring都會返回同一個Plaything實(shí)例。

下面的例子展示了如何創(chuàng)建一個單實(shí)例的Bean

package com.example.demo.bean;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Kid {

    private Plaything plaything;

    @Autowired
    public void setPlaything(Plaything plaything) {
        this.plaything = plaything;
    }

    public Plaything getPlaything() {
        return plaything;
    }
}
package com.example.demo.bean;

import org.springframework.stereotype.Component;

@Component
public class Plaything {

    public Plaything() {
        System.out.println("Plaything constructor run ...");
    }
}

??這里可以在Plaything類加上@Scope(BeanDefinition.SCOPE_SINGLETON),但是因?yàn)槭悄J(rèn)作用域是Singleton,所以沒必要加。

package com.example.demo.configuration;

import com.example.demo.bean.Kid;
import com.example.demo.bean.Plaything;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanScopeConfiguration {

    @Bean
    public Kid kid1(Plaything plaything1) {
        Kid kid = new Kid();
        kid.setPlaything(plaything1);
        return kid;
    }

    @Bean
    public Kid kid2(Plaything plaything2) {
        Kid kid = new Kid();
        kid.setPlaything(plaything2);
        return kid;
    }
}


package com.example.demo.application;

import com.example.demo.bean.Kid;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;


@SpringBootApplication
@ComponentScan("com.example")
public class DemoApplication {

    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(DemoApplication.class);
        context.getBeansOfType(Kid.class).forEach((name, kid) -> {
            System.out.println(name + " : " + kid.getPlaything());
        });
    }

}

??在Spring IoC容器的工作中,掃描過程只會創(chuàng)建bean的定義,真正的bean實(shí)例是在需要注入或者通過getBean方法獲取時才會創(chuàng)建。這個過程被稱為bean的初始化。

??這里運(yùn)行 ctx.getBeansOfType(Kid.class).forEach((name, kid) -> System.out.println(name + " : " + kid.getPlaything())); 時,Spring IoC容器會查找所有的Kid類型的bean定義,然后為每一個找到的bean定義創(chuàng)建實(shí)例(如果這個bean定義還沒有對應(yīng)的實(shí)例),并注入相應(yīng)的依賴。

運(yùn)行結(jié)果:
Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用

??三個 KidPlaything bean是相同的,說明默認(rèn)情況下 Plaything 是一個單例bean,整個Spring應(yīng)用中只有一個 Plaything bean被創(chuàng)建。

為什么會有3kid?

  1. Kid: 這個是通過在Kid類上標(biāo)注的@Component注解自動創(chuàng)建的。Spring在掃描時發(fā)現(xiàn)這個注解,就會自動在IOC容器中注冊這個bean。這個Bean的名字默認(rèn)是將類名的首字母小寫kid

  2. kid1: 在 BeanScopeConfiguration 中定義,通過kid1(Plaything plaything1)方法創(chuàng)建,并且注入了plaything1

  3. kid2: 在 BeanScopeConfiguration 中定義,通過kid2(Plaything plaything2)方法創(chuàng)建,并且注入了plaything2。

2.2 singleton作用域線程安全問題

需要注意的是,雖然singleton Bean只會有一個實(shí)例,但Spring并不會解決其線程安全問題,開發(fā)者需要根據(jù)實(shí)際場景自行處理。

我們通過一個代碼示例來說明在多線程環(huán)境中出現(xiàn)singleton Bean的線程安全問題。

首先,我們創(chuàng)建一個名為Countersingleton Bean,這個Bean有一個count變量,提供increment方法來增加count的值:

package com.example.demo.bean;

import org.springframework.stereotype.Component;

@Component
public class Counter {

    private int count = 0;

    public int increment() {
        return ++count;
    }
}

然后,我們創(chuàng)建一個名為CounterServicesingleton Bean,這個Bean依賴于Counter,在increaseCount方法中,我們調(diào)用counter.increment方法:

package com.example.demo.service;

import com.example.demo.bean.Counter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class CounterService {
	@Autowired
    private final Counter counter;

    public void increaseCount() {
        counter.increment();
    }
}

??我們在多線程環(huán)境中調(diào)用counterService.increaseCount方法時,就可能出現(xiàn)線程安全問題。因?yàn)?code>counter.increment方法并非線程安全,多個線程同時調(diào)用此方法可能會導(dǎo)致count值出現(xiàn)預(yù)期外的結(jié)果。

??要解決這個問題,我們需要使counter.increment方法線程安全。

??這里可以使用原子變量,在Counter類中,我們可以使用AtomicInteger來代替int類型的count,因?yàn)?code>AtomicInteger類中的方法是線程安全的,且其性能通常優(yōu)于synchronized關(guān)鍵字。

package com.example.demo.bean;

import org.springframework.stereotype.Component;

import java.util.concurrent.atomic.AtomicInteger;

@Component
public class Counter {
    private AtomicInteger count = new AtomicInteger(0);

    public int increment() {
        return count.incrementAndGet();
    }
}

??盡管優(yōu)化后已經(jīng)使Counter類線程安全,但在設(shè)計(jì)Bean時,我們應(yīng)該盡可能地減少可變狀態(tài)。這是因?yàn)榭勺儬顟B(tài)使得并發(fā)編程變得復(fù)雜,而無狀態(tài)的Bean通常更容易理解和測試。

??什么是無狀態(tài)的Bean呢? 如果一個Bean不持有任何狀態(tài)信息,也就是說,同樣的輸入總是會得到同樣的輸出,那么這個Bean就是無狀態(tài)的。反之,則是有狀態(tài)的Bean。


3. prototype作用域

3.1 prototype作用域的定義和用途

prototype作用域中,Spring容器會為每個請求創(chuàng)建一個新的bean實(shí)例。

例如,我們定義一個名為Plaything的類,并將其作用域設(shè)置為prototype

package com.example.demo.bean;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class Plaything {

    public Plaything() {
        System.out.println("Plaything constructor run ...");
    }
}

在這個例子中,Plaything是一個prototype作用域的bean。每次我們請求這個bean,Spring都會創(chuàng)建一個新的Plaything實(shí)例。

我們只需要修改上面的Plaything類,其他的類不用動。

打印結(jié)果:

Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用

這個@Scope(BeanDefinition.SCOPE_PROTOTYPE)可以寫成@Scope("prototype"),按照規(guī)范,還是利用已有的常量比較好。

Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用

3.2 prototype作用域在開發(fā)中的例子

??以我個人來說,我在excel多線程上傳的時候用到過這個,當(dāng)時是EasyExcel框架,我給一部分關(guān)鍵代碼展示一下如何在Spring中使用prototype作用域來處理多線程環(huán)境下的任務(wù)(實(shí)際業(yè)務(wù)會更復(fù)雜),大家可以對比,如果用prototype作用域和使用new對象的形式在實(shí)際開發(fā)中有什么區(qū)別。

使用prototype作用域的例子

@Resource
private ApplicationContext context;

@PostMapping("/user/upload")
public ResultModel upload(@RequestParam("multipartFile") MultipartFile multipartFile) {
	......
	ExecutorService es = new ThreadPoolExceutor(10, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(2000), new ThreadPoolExecutor.CallerRunPolicy());
	......
	EasyExcel.read(multipartFile.getInputStream(), UserDataUploadVO.class, 
		new PageReadListener<UserDataUploadVO>(dataList ->{
		......
		// 多線程處理上傳excel數(shù)據(jù),重點(diǎn)只看這一句話
			Future<?> future = es.submit(context.getBean(AsyncUploadHandler.class, user, dataList, errorCount));
		......
		})).sheet().doRead();
	......
}

??有人可能會問這里為什么使用context.getBean,而不是@Resource@Autowired注解,@Resource@Autowired注解只會在注入時創(chuàng)建一個新的實(shí)例,這里并不會反復(fù)注入。ApplicationContext.getBean()方法是在每次調(diào)用時解析的,所以它會在每次調(diào)用時創(chuàng)建一個新的AsyncUploadHandler實(shí)例。

AsyncUploadHandler.java

@Component
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class AsyncUploadHandler implements Runnable {

	private User user;
	
	private List<UserDataUploadVO> dataList;
	
	private AtomicInteger errorCount;
	
	@Resource
	private RedisService redisService;
	
	......
	
	@Resource
	private CompanyManagementMapper companyManagementMapper;

	public AsyncUploadHandler(user, List<UserDataUploadVO> dataList, AtomicInteger errorCount) {
		this.user = user;
		this.dataList = dataList;
		this.errorCount = errorCount;
	}

	@Override
	public void run() {
		......
	}
	
	......
}

??AsyncUploadHandler類是一個prototype作用域的bean,它被用來處理上傳的Excel數(shù)據(jù)。由于并發(fā)上傳的每個任務(wù)可能需要處理不同的數(shù)據(jù),并且可能需要在不同的用戶上下文中執(zhí)行,因此每個任務(wù)都需要有自己的AsyncUploadHandler bean。這就是為什么需要將AsyncUploadHandler定義為prototype作用域的原因。

??由于AsyncUploadHandler是由Spring管理的,我們可以直接使用@Resource注解來注入其他的bean,例如RedisServiceCompanyManagementMapper。

??如果用單例作用域的AsyncUploadHandler bean行不行?

??如果AsyncUploadHandler 對象被定義為一個單例作用域的Spring Bean,那么所有的線程都會共享同一個AsyncUploadHandler 對象。這可能會導(dǎo)致線程安全問題,因?yàn)槎鄠€線程同時修改同一個對象的狀態(tài)可能會導(dǎo)致數(shù)據(jù)不一致,這里我們需要的是每個用戶的數(shù)據(jù)都要上傳校驗(yàn)處理等邏輯(用戶數(shù)據(jù)在dataList里面),如果是單例AsyncUploadHandler,AsyncUploadHandler對象里面的dataList屬性會因其他線程的影響而導(dǎo)致被修改。

??把AsyncUploadHandler交給Spring容器管理,里面依賴的容器對象可以直接用@Resource注解注入。如果采用new出來的對象,那么這些對象只能從外面注入好了再傳入進(jìn)去。

不使用prototype作用域改用new對象的例子

@PostMapping("/user/upload")
public ResultModel upload(@RequestParam("multipartFile") MultipartFile multipartFile) {
	......
	ExecutorService es = new ThreadPoolExceutor(10, 16, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(2000), new ThreadPoolExecutor.CallerRunPolicy());
	......
	EasyExcel.read(multipartFile.getInputStream(), UserDataUploadVO.class, 
		new PageReadListener<UserDataUploadVO>(dataList ->{
		......
		// 多線程處理上傳excel數(shù)據(jù)
			Future<?> future = es.submit(new AsyncUploadHandler(user, dataList, errorCount, redisService, companyManagementMapper));
		......
		})).sheet().doRead();
	......
}

AsyncUploadHandler.java

public class AsyncUploadHandler implements Runnable {

	private User user;
	
	private List<UserDataUploadVO> dataList;
	
	private AtomicInteger errorCount;
	
	private RedisService redisService;
	
	private CompanyManagementMapper companyManagementMapper;
	
	......

	public AsyncUploadHandler(user, List<UserDataUploadVO> dataList, AtomicInteger errorCount, 
						RedisService redisService, CompanyManagementMapper companyManagementMapper) {
		this.user = user;
		this.dataList = dataList;
		this.errorCount = errorCount;
		this.redisService = redisService;
		this.companyManagementMapper = companyManagementMapper;
	}

	@Override
	public void run() {
		......
	}
	
	......
}

??如果直接新建AsyncUploadHandler對象,則需要手動傳入所有的依賴,這會使代碼變得更復(fù)雜更難以管理,而且還需要手動管理AsyncUploadHandler的生命周期。

3.3 prototype作用域在bean之間相互依賴時存在的問題

??在后續(xù)寫文章時,評論區(qū)有提問:“如果Bean A依賴Bean B,那如果在配置類中先定義Bean B再定義Bean A,會不會有問題?還是說Spring會自動處理這種依賴關(guān)系?”

這個問題我發(fā)現(xiàn)在原型作用域這個點(diǎn)還需要再補(bǔ)充講解一下:

??這種情況在沒有相互依賴的情況下不會有問題,Spring會在先解析配置類和@Bean方法,獲得所有Bean的依賴信息,之后Spring根據(jù)依賴關(guān)系決定Bean的實(shí)例化順序,而不管配置類中定義的順序。

??如果A依賴BB依賴A形成循環(huán)依賴,對于單例Bean,Spring通過三級緩存機(jī)制來解決。對于原型Bean 的循環(huán)依賴無法解決,會拋出BeanCurrentlyInCreationException異常,原因是原型Bean每次都會創(chuàng)建新實(shí)例,Spring無法管理其完整生命周期。

??注意:Spring解析配置類和@Bean方法是在BeanDefinitionReader進(jìn)行的,這是 refresh 過程的一個步驟。


4. request作用域(了解)

??request作用域:Bean在一個HTTP請求內(nèi)有效。當(dāng)請求開始時,Spring容器會為每個新的HTTP請求創(chuàng)建一個新的Bean實(shí)例,這個Bean在當(dāng)前HTTP請求內(nèi)是有效的,請求結(jié)束后,Bean就會被銷毀。如果在同一個請求中多次獲取該Bean,就會得到同一個實(shí)例,但是在不同的請求中獲取的實(shí)例將會不同。

@Component
@Scope(value = WebApplicationContext.SCOPE_REQUEST, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class RequestScopedBean {
    // 在一次Http請求內(nèi)共享的數(shù)據(jù)
    private String requestData;

    public void setRequestData(String requestData) {
        this.requestData = requestData;
    }

    public String getRequestData() {
        return this.requestData;
    }
}

上述Bean在一個HTTP請求的生命周期內(nèi)是一個單例,每個新的HTTP請求都會創(chuàng)建一個新的Bean實(shí)例。


5. session作用域(了解)

??session作用域:Bean是在同一個HTTP會話(Session)中是單例的。也就是說,從用戶登錄開始,到用戶退出登錄(或者Session超時)結(jié)束,這個過程中,不管用戶進(jìn)行了多少次HTTP請求,只要是在同一個會話中,都會使用同一個Bean實(shí)例。

@Component
@Scope(value = WebApplicationContext.SCOPE_SESSION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionScopedBean {
    // 在一個Http會話內(nèi)共享的數(shù)據(jù)
    private String sessionData;

    public void setSessionData(String sessionData) {
        this.sessionData = sessionData;
    }

    public String getSessionData() {
        return this.sessionData;
    }
}

??這樣的設(shè)計(jì)對于存儲和管理會話級別的數(shù)據(jù)非常有用,例如用戶的登錄信息、購物車信息等。因?yàn)樗鼈兪窃谕粋€會話中保持一致的,所以使用session作用域的Bean可以很好地解決這個問題。

??但是實(shí)際開發(fā)中沒人這么干,會話id都會存在數(shù)據(jù)庫,根據(jù)會話id就能在各種表中獲取數(shù)據(jù),避免頻繁查庫也是把關(guān)鍵信息序列化后存在Redis。


6. application作用域(了解)

??application作用域:在整個Web應(yīng)用的生命周期內(nèi),Spring容器只會創(chuàng)建一個Bean實(shí)例。這個BeanWeb應(yīng)用的生命周期內(nèi)都是有效的,當(dāng)Web應(yīng)用停止后,Bean就會被銷毀。

@Component
@Scope(value = WebApplicationContext.SCOPE_APPLICATION, proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ApplicationScopedBean {
    // 在整個Web應(yīng)用的生命周期內(nèi)共享的數(shù)據(jù)
    private String applicationData;

    public void setApplicationData(String applicationData) {
        this.applicationData = applicationData;
    }

    public String getApplicationData() {
        return this.applicationData;
    }
}

??如果在一個application作用域的Bean上調(diào)用setter方法,那么這個變更將對所有用戶和會話可見。后續(xù)對這個Bean的所有調(diào)用(包括gettersetter)都將影響到同一個Bean實(shí)例,后面的調(diào)用會覆蓋前面的狀態(tài)。


7. websocket作用域(了解)

??websocket作用域:Bean 在每一個新的 WebSocket 會話中都會被創(chuàng)建一次,就像 session 作用域的 Bean 在每一個 HTTP 會話中都會被創(chuàng)建一次一樣。這個Bean在整個WebSocket會話內(nèi)都是有效的,當(dāng)WebSocket會話結(jié)束后,Bean就會被銷毀。

@Component
@Scope(value = "websocket", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class WebSocketScopedBean {
    // 在一個WebSocket會話內(nèi)共享的數(shù)據(jù)
    private String socketData;

    public void setSocketData(String socketData) {
        this.socketData = socketData;
    }

    public String getSocketData() {
        return this.socketData;
    }
}

上述Bean在一個WebSocket會話的生命周期內(nèi)是一個單例,每個新的WebSocket會話都會創(chuàng)建一個新的Bean實(shí)例。

這個作用域需要Spring Websocket模塊支持,并且應(yīng)用需要配置為使用websocket。文章來源地址http://www.zghlxwxcb.cn/news/detail-478672.html



歡迎一鍵三連~

有問題請留言,大家一起探討學(xué)習(xí)

----------------------Talk is cheap, show me the code-----------------------

到了這里,關(guān)于Spring高手之路4——深度解析Spring內(nèi)置作用域及其在實(shí)踐中的應(yīng)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Spring Boot深度解析:是什么、為何使用及其優(yōu)勢所在

    在Java企業(yè)級應(yīng)用開發(fā)的漫長歷史中,Spring框架以其卓越的依賴注入和面向切面編程的能力,贏得了廣大開發(fā)者的青睞。然而,隨著技術(shù)的不斷進(jìn)步和項(xiàng)目的日益復(fù)雜,傳統(tǒng)的Spring應(yīng)用開發(fā)流程逐漸顯得繁瑣和低效。為了解決這一問題,Spring Boot應(yīng)運(yùn)而生,它極大地簡化了Spr

    2024年04月11日
    瀏覽(26)
  • Spring高手之路-Spring的AOP失效場景詳解

    目錄 前言 1.非Spring管理的對象 2.同一個Bean內(nèi)部方法調(diào)用 3.靜態(tài)方法 4.final方法 5.異步方法 總結(jié) Spring的AOP(面向切面編程)是一種強(qiáng)大的技術(shù),用于在應(yīng)用程序中實(shí)現(xiàn)橫切關(guān)注點(diǎn)的模塊化。雖然Spring的AOP在大多數(shù)情況下都是有效的,但在某些場景下可能會失效。下面來分析

    2024年01月21日
    瀏覽(28)
  • Spring高手之路-SpringBean的生命周期

    Spring高手之路-SpringBean的生命周期

    目錄 SpringBean的生命周期 整體介紹 詳細(xì)介紹 1.實(shí)例化Bean 2.設(shè)置屬性值 3.檢查Aware 4.調(diào)用BeanPostProcessor的前置處理方法 5.調(diào)用InitializingBean的afterPropertiesSet方法 6.調(diào)用自定義init-method方法 7.調(diào)用BeanPostProcessor的后置處理方法 8.注冊Destruction回調(diào) 9.Bean準(zhǔn)備就緒 10.調(diào)用DisposableBean的d

    2024年02月03日
    瀏覽(23)
  • Spring高手之路-Spring在業(yè)務(wù)中常見的使用方式

    目錄 通過IOC實(shí)現(xiàn)策略模式 通過AOP實(shí)現(xiàn)攔截增強(qiáng) 1.參數(shù)檢驗(yàn) 2.緩存邏輯 3.日志記錄 通過Event異步解耦 通過Spring管理事務(wù) 1.聲明式事務(wù) 2.編程式事務(wù) 3.需要注意的問題 不能在事務(wù)中處理分布式緩存 不能在事務(wù)中執(zhí)行 RPC 操作 不過度使用聲明式事務(wù) 很多時候,我們需要對不同的

    2024年01月19日
    瀏覽(22)
  • Spring高手之路9——掌握Spring條件裝配的秘密武器

    Spring高手之路9——掌握Spring條件裝配的秘密武器

    ??在 Spring 框架中,條件裝配( Conditional Configuration )是一個非常重要的特性,它允許開發(fā)者根據(jù)滿足的條件,動態(tài)地進(jìn)行 Bean 的注冊或是創(chuàng)建。這樣就可以根據(jù)不同的環(huán)境或配置,創(chuàng)建不同的 Bean 實(shí)例,這一特性對于創(chuàng)建可配置和模塊化的應(yīng)用是非常有用的。 Spring 提供了一

    2024年02月16日
    瀏覽(23)
  • Spring高手之路10——解鎖Spring組件掃描的新視角

    Spring高手之路10——解鎖Spring組件掃描的新視角

    ??首先,我們將探討一些 Spring 框架中 IOC ( Inversion of Control )的高級特性,特別是組件掃描的相關(guān)知識。組件掃描是 Spring 框架中一個重要的特性,它可以自動檢測并實(shí)例化帶有特定注解(如 @Component , @Service , @Controller 等)的類,并將它們注冊為 Spring 上下文中的 bean 。這

    2024年02月16日
    瀏覽(26)
  • Spring MVC 深度解析與應(yīng)用實(shí)踐

    Spring MVC(Model-View-Controller)是 Spring 框架的一部分,專門用于設(shè)計(jì)創(chuàng)建分層的 Java Web 應(yīng)用。它是一個全功能的 MVC 模塊,能夠提供強(qiáng)大的配置選項(xiàng),并利用默認(rèn)的約定,使基本項(xiàng)目的配置降至最低。Spring MVC 提供了一種分離的方式,使得能夠通過控制器(Controller)進(jìn)行業(yè)務(wù)處

    2024年02月11日
    瀏覽(15)
  • Spring高手之路5——徹底掌握Bean的生命周期

    Spring高手之路5——徹底掌握Bean的生命周期

    在 Spring IOC 容器中, Bean 的生命周期大致如下: 實(shí)例化:當(dāng)啟動 Spring 應(yīng)用時, IOC 容器就會為在配置文件中聲明的每個 bean 創(chuàng)建一個實(shí)例。 屬性賦值:實(shí)例化后, Spring 就通過反射機(jī)制給 Bean 的屬性賦值。 調(diào)用初始化方法:如果 Bean 配置了初始化方法, Spring 就會調(diào)用它。

    2024年02月09日
    瀏覽(20)
  • Spring高手之路-@Autowired和@Resource注解異同點(diǎn)

    Spring高手之路-@Autowired和@Resource注解異同點(diǎn)

    目錄 概述 相同點(diǎn) 1.都可以實(shí)現(xiàn)依賴注入 2.都可以用于注入任意類型的Bean 3.都支持通過名稱、類型匹配進(jìn)行注入 不同點(diǎn) 1.來源不同。 2.包含的屬性不同 3.匹配方式(裝配順序)不同。 4.支持的注入對象類型不同 5.應(yīng)用地方不同 @Autowired 和 @Resource 是在 Java 開發(fā)中用于實(shí)現(xiàn)依賴

    2024年02月03日
    瀏覽(26)
  • Spring高手之路8——Spring Bean模塊裝配的藝術(shù):@Import詳解

    Spring高手之路8——Spring Bean模塊裝配的藝術(shù):@Import詳解

    ??在 Spring 中,手動裝配通常是指通過 XML 配置文件明確指定 Bean 及其依賴,或者在代碼中直接使用 new 創(chuàng)建對象并設(shè)定依賴關(guān)系。 ??然而,隨著 Spring 2.0 引入注解,以及 Spring 3.0 全面支持注解驅(qū)動開發(fā),這個過程變得更加自動化。例如,通過使用 @Component + @Compo

    2024年02月13日
    瀏覽(25)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包