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

Spring注入bean的四種方式總結(jié)

 更新時(shí)間:2025年11月27日 09:11:46   作者:K***6589  
我們談到Spring的時(shí)候一定會提到IOC容器、DI依賴注入,Spring通過將一個(gè)個(gè)類標(biāo)注為Bean的方法注入到IOC容器中,達(dá)到了控制反轉(zhuǎn)的效果,Spring幫我們實(shí)現(xiàn)了一種通過注解來實(shí)現(xiàn)注入的方法,所以本文為大家介紹了Spring注入bean的四種方式,需要的朋友可以參考下

一提到 Spring,大家最先想到的是啥?是 AOPIOC 的兩大特性?是 SpringBean 的初始化流程?還是基于 SpringSpring Cloud 全家桶呢?

今天我們就從 SpringIOC 特性入手,聊一聊 Spring 中把 Bean 注入 Spring 容器的幾種方式。

我們先來簡單了解下 IOC 的概念:IOC控制反轉(zhuǎn),也稱為 依賴注入,是指將 對象的創(chuàng)建 或者 依賴關(guān)系的引用 從具體的對象控制轉(zhuǎn)為框架或者 IOC 容器來完成,也就是依賴對象的獲得被反轉(zhuǎn)了。

可以簡單理解為原來由我們來創(chuàng)建對象,現(xiàn)在由 Spring 來創(chuàng)建并控制對象。

一、xml 方式

依稀記得最早接觸 Spring 的時(shí)候,用的還是 SSH 框架,不知道大家對這個(gè)還有印象嗎?所有的 bean 的注入得依靠 xml 文件來完成。

它的注入方式分為:set 方法注入、構(gòu)造方法注入、字段注入,而注入類型分為值類型注入(8 種基本數(shù)據(jù)類型)和引用類型注入(將依賴對象注入)。

以下是 set 方法注入的簡單示例:

<bean name="teacher" class="org.springframework.demo.model.Teacher">
    <property name="name" value="張老師"></property>
</bean>

對應(yīng)的實(shí)體類代碼:

public class Teacher {
	private String name;
	
	public void setName(String name) {
		this.name = name;
	}
}

xml方式存在的缺點(diǎn)如下:

  1. xml 文件配置起來比較麻煩,既要維護(hù)代碼又要維護(hù)配置文件,開發(fā)效率低;
  2. 項(xiàng)目中配置文件過多,維護(hù)起來比較困難;
  3. 程序編譯期間無法對配置項(xiàng)的正確性進(jìn)行驗(yàn)證,只能在運(yùn)行期發(fā)現(xiàn)并且出錯(cuò)之后不易排查;
  4. 解析 xml 時(shí),無論是將 xml 一次性裝進(jìn)內(nèi)存,還是一行一行解析,都會占用內(nèi)存資源,影響性能。

二、注解方式

隨著 Spring 的發(fā)展,Spring 2.5 開始出現(xiàn)了一系列注解,除了我們經(jīng)常使用的@Controller、@Service@Repository、@Component 之外,還有一些比較常用的方式,接下來我們簡單了解下。

@Configuration + @Bean

當(dāng)我們需要引入第三方的 jar 包時(shí),可以用 @Bean 注解來標(biāo)注,同時(shí)需要搭配 @Configuration 來使用。

  • @Configuration 用來聲明一個(gè)配置類,可以理解為 xml<beans> 標(biāo)簽
  • @Bean 用來聲明一個(gè) bean,將其加入到 Spring 容器中,可以理解為 xml<bean> 標(biāo)簽

簡單樣例:將 RedisTemplate 注入 Spring

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        ......
        return redisTemplate;
    }
}

@Import

我們在翻看 Spring 源碼的過程中,經(jīng)常會看到 @Import 注解,它也可以用來將第三方 jar 包注入 Spring,但是它只可以作用在類上。

例如在注解 EnableSpringConfigured 上就包含了 @Import 注解,用于將 SpringConfiguredConfiguration 配置文件加載進(jìn) Spring 容器。

@Import(SpringConfiguredConfiguration.class)
public @interface EnableSpringConfigured {}

@Importvalue 值是一個(gè)數(shù)組,一個(gè)一個(gè)注入比較繁瑣,因此我們可以搭配 ImportSelector 接口來使用,用法如下:

@Configuration
@Import(MyImportSelector.class)
public class MyConfig {}

public class MyImportSelector implements ImportSelector {
 @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        return new String[]{"org.springframework.demo.model.Teacher","org.springframework.demo.model.Student"};
    }
}

其中 selectImports 方法返回的數(shù)組就會通過 @Import 注解注入到 Spring 容器中。

無獨(dú)有偶,ImportBeanDefinitionRegistrar 接口也為我們提供了注入 bean 的方法。

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    ......
}

我們點(diǎn)擊 AspectJAutoProxyRegistrar 類,發(fā)現(xiàn)它實(shí)現(xiàn)了 ImportBeanDefinitionRegistrar 接口,它的 registerBeanDefinitions 方法便是注入 bean 的過程,可以參考下。

如果覺得源代碼比較難懂,可以看一下我們自定義的類:

@Configuration
@Import(value = {MyImportBeanDefinitionRegistrar.class})
public class MyConfig {}

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
                                        BeanDefinitionRegistry registry) {
            RootBeanDefinition tDefinition = new RootBeanDefinition(Teacher.class);
            // 注冊 Bean,并指定bean的名稱和類型
            registry.registerBeanDefinition("teacher", tDefinition);
        }
    }
}

這樣我們就把 Teacher 類注入到 Spring 容器中了。

三、FactoryBean

提到 FactoryBean,就不得不與 BeanFactory 比較一番。

  • BeanFactory : 是 Factory, IOC 容器或者對象工廠,所有的 Bean 都由它進(jìn)行管理
  • FactoryBean : 是 Bean ,是一個(gè)能產(chǎn)生或者修飾對象生成的工廠 Bean,實(shí)現(xiàn)與工廠模式和修飾器模式類似

那么 FactoryBean 是如何實(shí)現(xiàn) bean 注入的呢?

先定義實(shí)現(xiàn)了 FactoryBean 接口的類

public class TeacherFactoryBean implements FactoryBean<Teacher> {

	 /**
	  * 返回此工廠管理的對象實(shí)例
	  **/
	 @Override
	 public Teacher getObject() throws Exception {
	  	return new Teacher();
	 }
	
	 /**
	  * 返回此 FactoryBean 創(chuàng)建的對象的類型
	  **/
	 @Override
	 public Class<?> getObjectType() {
	  	return Teacher.class;
	 }

}

然后通過 @Configuration + @Bean 的方式將 TeacherFactoryBean 加入到容器中

@Configuration
public class MyConfig {
	 @Bean
	 public TeacherFactoryBean teacherFactoryBean(){
	  	return new TeacherFactoryBean();
	 }
}

注意:我們沒有向容器中注入 Teacher,而是直接注入的 TeacherFactoryBean,然后從容器中拿 Teacher 這個(gè)類型的 bean,成功運(yùn)行。

四、BDRegistryPostProcessor

看到這個(gè)接口,不知道對于翻看過 Spring 源碼的你來說熟不熟悉。如果不熟悉的話請往下看,要是熟悉的話就再看一遍吧。

源碼

public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
    // 注冊bean到spring容器中
 	void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}

@FunctionalInterface
public interface BeanFactoryPostProcessor {
 	void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}

BeanFactoryPostProcessor 接口是 BeanFactory 的后置處理器,方法postProcessBeanFactorybean 的定義進(jìn)行控制。今天我們重點(diǎn)來看看 postProcessBeanDefinitionRegistry 方法:它的參數(shù)是 BeanDefinitionRegistry,顧名思義就是與 BeanDefinition 注冊相關(guān)的。

通過觀察該類,我們發(fā)現(xiàn)它里邊包含了 registerBeanDefinition 方法,這個(gè)不就是我們想要的嗎?為了能更好的使用該接口來達(dá)到注入 bean 的目的,我們先來看看 Spring 是如何操作此接口的。

看下 invokeBeanFactoryPostProcessors 方法,會發(fā)現(xiàn)沒有實(shí)現(xiàn) PriorityOrdered和Orderedbean(這種跟我們自定義的實(shí)現(xiàn)類有關(guān))會執(zhí)行以下代碼。

while (reiterate) {
    ......
    invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    ......
}

進(jìn)入該方法

private static void invokeBeanDefinitionRegistryPostProcessors(
    Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, 
    BeanDefinitionRegistry registry) {

    for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
        postProcessor.postProcessBeanDefinitionRegistry(registry);
    }
}

會發(fā)現(xiàn)實(shí)現(xiàn)了 BeanDefinitionRegistryPostProcessor 接口的 bean,其 postProcessBeanDefinitionRegistry 方法會被調(diào)用,也就是說如果我們自定義接口實(shí)現(xiàn)該接口,它的 postProcessBeanDefinitionRegistry 方法也會被執(zhí)行。

實(shí)戰(zhàn)

話不多說,直接上代碼。自定義接口實(shí)現(xiàn)類

public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

	 /**
	  * 初始化過程中先執(zhí)行
	  **/
	 @Override
	 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		  RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Teacher.class);
		  //Teacher 的定義注冊到spring容器中
		  registry.registerBeanDefinition("teacher", rootBeanDefinition);
	 }
	
	 /**
	  * 初始化過程中后執(zhí)行
	  **/
	 @Override
	 public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {}
}

啟動類代碼

public static void main(String[] args) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    MyBeanDefinitionRegistryPostProcessor postProcessor = new MyBeanDefinitionRegistryPostProcessor();
    // 將自定義實(shí)現(xiàn)類加入 Spring 容器
    context.addBeanFactoryPostProcessor(postProcessor);
    context.refresh();
    Teacher bean = context.getBean(Teacher.class);
    System.out.println(bean);
}

啟動并打印結(jié)果

org.springframework.demo.model.Teacher@2473d930

發(fā)現(xiàn)已經(jīng)注入到 Spring 容器中了。

以上就是我們總結(jié)的幾種將 bean 注入 Spring 容器的方式,趕快行動起來實(shí)戰(zhàn)演練一下吧??!

到此這篇關(guān)于Spring注入bean的四種方式總結(jié)的文章就介紹到這了,更多相關(guān)Spring注入bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot集成MongoDB的實(shí)現(xiàn)

    SpringBoot集成MongoDB的實(shí)現(xiàn)

    本文主要介紹了SpringBoot集成MongoDB的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-01-01
  • 基于Protobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序

    基于Protobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序

    下面小編就為大家?guī)硪黄赑rotobuf動態(tài)解析在Java中的應(yīng)用 包含例子程序。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-07-07
  • SpringBoot整合Docker實(shí)現(xiàn)一次構(gòu)建到處運(yùn)行的操作方法

    SpringBoot整合Docker實(shí)現(xiàn)一次構(gòu)建到處運(yùn)行的操作方法

    本文講解的是 SpringBoot 引入容器化技術(shù) Docker 實(shí)現(xiàn)一次構(gòu)建到處運(yùn)行,包括鏡像構(gòu)建、Docker倉庫搭建使用、Docker倉庫可視化UI等內(nèi)容,需要的朋友可以參考下
    2022-10-10
  • java編程枚舉類型那些事!枚舉類型定義和重寫枚舉的方法

    java編程枚舉類型那些事!枚舉類型定義和重寫枚舉的方法

    本文主要介紹了枚舉類型的有關(guān)內(nèi)容,涉及簡單的枚舉類型定義,以及枚舉類型的值在Java中的定義方法,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-10-10
  • 史上最全的java隨機(jī)數(shù)生成算法分享

    史上最全的java隨機(jī)數(shù)生成算法分享

    這篇文章主要介紹了史上最全的java隨機(jī)數(shù)生成算法,我分享一個(gè)最全的隨機(jī)數(shù)的生成算法,最代碼的找回密碼的隨機(jī)數(shù)就是用的這個(gè)方法
    2014-01-01
  • 在Spring中配置Quartz的三種方式

    在Spring中配置Quartz的三種方式

    Spring Quartz 是一個(gè)任務(wù)調(diào)度框架,它允許我們定期執(zhí)行特定的任務(wù),在 Spring 中,我們可以通過多種方式來配置 Quartz,包括使用 ??@Scheduled?? 注解、XML 配置和 Java 配置,本文將介紹如何在 Spring 中使用這三種方式來配置 Quartz,需要的朋友可以參考下
    2025-01-01
  • SpringCloud2020整合Nacos-Bootstrap配置不生效的解決

    SpringCloud2020整合Nacos-Bootstrap配置不生效的解決

    這篇文章主要介紹了SpringCloud2020整合Nacos-Bootstrap配置不生效的解決,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • nacos在liunx系統(tǒng)中啟動成功瀏覽器卻訪問不了的解決方法

    nacos在liunx系統(tǒng)中啟動成功瀏覽器卻訪問不了的解決方法

    在linux下搭建nacos,現(xiàn)在想要啟動,訪問nacos頁面,訪問不了,所以本文小編將給大家介紹nacos在liunx系統(tǒng)中啟動成功,瀏覽器卻訪問不了?全面的解決辦法,需要的朋友可以參考下
    2023-09-09
  • springBoot靜態(tài)資源加載不到,并且配置了也不生效問題及解決

    springBoot靜態(tài)資源加載不到,并且配置了也不生效問題及解決

    這篇文章總結(jié)了一個(gè)在Spring Boot 2.6.x版本中,由于路徑匹配策略改變導(dǎo)致靜態(tài)資源無法加載的問題,并提供了解決方案:通過配置類或在配置文件中設(shè)置路徑匹配策略為AntPathMatcher,或者直接降級Spring Boot版本
    2025-02-02
  • MyBatis執(zhí)行SQL查詢的完整流程

    MyBatis執(zhí)行SQL查詢的完整流程

    本文詳細(xì)介紹了MyBatis SQL執(zhí)行的完整過程,包括核心對象、代碼實(shí)現(xiàn)與執(zhí)行鏈路,通過編程式調(diào)用示例和流程圖,展示了從環(huán)境配置、SqlSession創(chuàng)建到結(jié)果獲取的全步驟,需要的朋友可以參考下
    2026-01-01

最新評論

五寨县| 积石山| 托克逊县| 井陉县| 色达县| 抚顺县| 嘉善县| 铜山县| 北宁市| 锡林郭勒盟| 彰化市| 通州区| 青龙| 紫云| 威信县| 美姑县| 固镇县| 扎赉特旗| 长泰县| 都安| 广平县| 海原县| 公安县| 太仓市| 江口县| 南充市| 颍上县| 常山县| 崇明县| 沙湾县| 韶关市| 汕头市| 西吉县| 永兴县| 合阳县| 广东省| 阿拉善左旗| 馆陶县| 蓝山县| 罗城| 崇阳县|