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

Spring容器注入bean的五種方法逐個(gè)解析

 更新時(shí)間:2023年02月20日 09:02:35   作者:尚少  
依賴(lài)注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個(gè)概念。具體含義是:當(dāng)某個(gè)角色(可能是一個(gè)Java實(shí)例,調(diào)用者)需要另一個(gè)角色(另一個(gè)Java實(shí)例,被調(diào)用者)的協(xié)助時(shí),在傳統(tǒng)的程序設(shè)計(jì)過(guò)程中,通常由調(diào)用者來(lái)創(chuàng)建被調(diào)用者的實(shí)例

前言

  我們?cè)陧?xiàng)目開(kāi)發(fā)中都用到Spring,知道對(duì)象是交由Spring去管理。那么將一個(gè)對(duì)象加入到Spring容器中,有幾種方法呢,我們來(lái)總結(jié)一下。

@ComponentScan+@Component

  @ComponentScan可以放在啟動(dòng)類(lèi)上,指定要掃描的包路徑;該包路徑下被@Component修飾的類(lèi),都會(huì)被注入到Spring容器中。

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "com.gs.beanRegister")
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        bean.say();
    }
}

  com.gs.beanRegister包下:

import org.springframework.stereotype.Component;
@Component
public class A {
    public void say() {
        System.out.println("這是a");
    }
}

  注:在SpringBoot中,由于其自動(dòng)裝配的特性,所以@ComponentScan可以不加,只要@Component修飾的類(lèi)和啟動(dòng)類(lèi)在同一包下或者在啟動(dòng)類(lèi)所在包的子包下。

@Configuration+@Bean

  @Configuration用來(lái)聲明一個(gè)配置類(lèi),如果它的方法被@Bean修飾,那么該方法返回的對(duì)象也會(huì)被注入到Spring容器中。

  代碼方面,BootStrap 類(lèi)不動(dòng),A類(lèi)的@Component去掉,com.gs.beanRegister包下建個(gè)配置類(lèi):

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Bean;
@Configuration
public class MyConfiguration {
    @Bean
    public A a() {
        return new A();
    }
}

通過(guò)@Import注解

  這個(gè)注解可能平時(shí)大家接觸得不多,它有好幾種使用方式。

1.直接導(dǎo)入類(lèi)的class

import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@Import(A.class)
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        //B bean = context.getBean(B.class);
        bean.say();
    }
}

  A類(lèi)不用添加任何注解:

public class A {
    public void say() {
        System.out.println("這是a");
    }
}

2.導(dǎo)入配置類(lèi)

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;
@Import(MyConfiguration.class)
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        bean.say();
    }
}
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
// 使用@Import導(dǎo)入配置類(lèi)時(shí),@Configuration可以不加
//@Configuration
public class MyConfiguration {
    @Bean
    public A a() {
        return new A();
    }
}

3.導(dǎo)入ImportSelector的實(shí)現(xiàn)類(lèi)

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;
@Import(MyImportSelector.class)
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        bean.say();
    }
}
import org.springframework.context.annotation.ImportSelector;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata metadata) {
        // 返回要注入的bean的全路徑,A類(lèi)不用任何注解修飾
        // SpringBoot的自動(dòng)裝配,就用到了這種方式:
        // 返回配置類(lèi)的全路徑,配置類(lèi)的@Bean方法返回的對(duì)象也能注入到容器中
        return new String[] { A.class.getName() };
    }
}

4.導(dǎo)入ImportBeanDefinitionRegistrar的實(shí)現(xiàn)類(lèi)

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;
@Import(MyImportBeanDefinitionRegistrar.class)
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        bean.say();
    }
}
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
public class MyImportBeanDefinitionRegistrar implements 
             ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata, 
                BeanDefinitionRegistry registry) {
        // 構(gòu)建bean的元數(shù)據(jù),A類(lèi)不用任何注解修飾
        // spring-mybatis掃描mapper接口,生成代理類(lèi),就是用的這種方式
        BeanDefinition definition = new RootBeanDefinition(A.class);
        registry.registerBeanDefinition("a", definition);
    }
}

借助FactoryBean接口

  實(shí)現(xiàn)FactoryBean接口的類(lèi),除了本身會(huì)被注入外,getObject方法返回的對(duì)象也會(huì)被注入到Spring容器中。

import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Import;
@Import(MyFactoryBean.class)
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext(BootStrap.class);
        A bean = context.getBean(A.class);
        bean.say();
    }
}
import org.springframework.beans.factory.FactoryBean;
public class MyFactoryBean implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new A();
    }
    @Override
    public Class<?> getObjectType() {
        return A.class;
    }
}

借助BeanDefinitionRegistryPostProcessor接口

  在Spring容器啟動(dòng)時(shí),會(huì)調(diào)用該接口的postProcessBeanDefinitionRegistry方法,大概意思是等BeanDefinition(上面提到的bean的元數(shù)據(jù))加載完成后,再對(duì)它進(jìn)行后置處理。所以可以在此調(diào)整BeanDefinition,從而把對(duì)應(yīng)的bean注入。

import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BootStrap {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = 
        new AnnotationConfigApplicationContext();
        BeanDefinitionRegistryPostProcessor postProcessor = 
        new MyBeanDefinitionRegistryPostProcessor();
        context.addBeanFactoryPostProcessor(postProcessor);
        context.refresh();
        A a = context.getBean(A.class);
        a.say();
    }
}
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
public class MyBeanDefinitionRegistryPostProcessor implements 
             BeanDefinitionRegistryPostProcessor {
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry 
                registry) throws BeansException {
        BeanDefinition definition = new RootBeanDefinition(A.class);
        registry.registerBeanDefinition("a", definition);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory 
                beanFactory) throws BeansException {
    }
}

到此這篇關(guān)于Spring容器注入bean的五種方法逐個(gè)解析的文章就介紹到這了,更多相關(guān)Spring注入bean內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis如何調(diào)用存儲(chǔ)過(guò)程與存儲(chǔ)函數(shù)

    MyBatis如何調(diào)用存儲(chǔ)過(guò)程與存儲(chǔ)函數(shù)

    這篇文章主要介紹了MyBatis如何調(diào)用存儲(chǔ)過(guò)程與存儲(chǔ)函數(shù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問(wèn)題及解決

    SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問(wèn)題及解決

    這篇文章主要介紹了SpringCloud-Gateway轉(zhuǎn)發(fā)WebSocket失敗問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 深入解析Java中volatile關(guān)鍵字的作用

    深入解析Java中volatile關(guān)鍵字的作用

    Java語(yǔ)言是支持多線程的,為了解決線程并發(fā)的問(wèn)題,在語(yǔ)言?xún)?nèi)部引入了 同步塊 和 volatile 關(guān)鍵字機(jī)制
    2013-09-09
  • Java空集合使用場(chǎng)景與填坑記錄

    Java空集合使用場(chǎng)景與填坑記錄

    這篇文章主要給大家介紹了關(guān)于Java空集合使用場(chǎng)景與填坑的相關(guān)資料,并且給大家介紹了java判斷集合是否為空的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2018-08-08
  • SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制

    SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制

    本文主要介紹了SpringBoot中MapStruct實(shí)現(xiàn)優(yōu)雅的數(shù)據(jù)復(fù)制,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • 一文給你通俗易懂的講解Java異常

    一文給你通俗易懂的講解Java異常

    這篇文章主要給大家介紹了關(guān)于Java異常的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • SpringBoot整合jasypt加密配置文件敏感信息

    SpringBoot整合jasypt加密配置文件敏感信息

    在項(xiàng)目中我們需要對(duì)配置文件的一些敏感信息進(jìn)行加密處理,比如數(shù)據(jù)庫(kù)賬戶(hù)密碼,避免直接暴露出來(lái),這種場(chǎng)景常常用于生產(chǎn)環(huán)境,我們不想讓開(kāi)發(fā)人員知道生產(chǎn)庫(kù)的密碼,有運(yùn)維人員統(tǒng)一管理,所以本文給大家介紹了SpringBoot整合jasypt加密配置文件敏感信息
    2024-06-06
  • mybatis輸出SQL格式化方式

    mybatis輸出SQL格式化方式

    這篇文章主要介紹了mybatis輸出SQL格式化方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • SpringBoot詳解如何進(jìn)行整合Druid數(shù)據(jù)源

    SpringBoot詳解如何進(jìn)行整合Druid數(shù)據(jù)源

    Druid是阿里開(kāi)發(fā)的一款開(kāi)源的數(shù)據(jù)源,被很多人認(rèn)為是Java語(yǔ)言中最好的數(shù)據(jù)庫(kù)連接池,本文主要介紹了SpringBoot整合Druid數(shù)據(jù)源的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • SpringBoot實(shí)現(xiàn)文件上傳與下載功能的示例代碼

    SpringBoot實(shí)現(xiàn)文件上傳與下載功能的示例代碼

    文件上傳與下載是Web應(yīng)用開(kāi)發(fā)中常用的功能之一。接下來(lái)我們將討論如何在Spring?Boot的Web應(yīng)用開(kāi)發(fā)中,如何實(shí)現(xiàn)文件的上傳與下載,感興趣的可以了解一下
    2022-06-06

最新評(píng)論