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

Spring bean注冊到容器的總結(jié)

 更新時間:2024年12月23日 09:43:08   作者:君莫Junmo  
這篇文章主要介紹了Spring bean注冊到容器的總結(jié),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

本文總結(jié)的是如何使用注解方式把對象加入ioc容器管理(永無止境,一直會更新).

來自作者的吐槽:好煩,他媽的提供這么多用法,然后那些 SpringBoot starter 框架里都是想用什么就用什么,導(dǎo)致看源碼理解度很痛苦,其實我感覺種類方式多了,反而丟失了規(guī)范,增加理解成本,真的很煩?。。。。。。。?!
注意:所有的使用方式皆來自Spring framework, SpringBoot不在本文討論之內(nèi)。

@Component + @ComponentScan

首先上場的運用最常用、最廣泛的方式。元注解延伸出去的@Controller、@Service、@Repository等都一樣。
容器bean名稱:默認(rèn)就是類名首字母小寫(app)
建議使用場景:自己項目中的類需要交給Spring管理。

@Component
public class App {
}

@Configuration + @Bean

其實@Configuration也是@Component,所以你用@Component也可以,至于為什么要這樣設(shè)計,應(yīng)該為了見名知意。可以通過@Bean的方式來自己構(gòu)建代碼的方式來構(gòu)建bean對象,然后塞入到Spring中,可以類似Spring會回調(diào)你的@Bean上的方法,將你自己定義創(chuàng)建的對象注入到Spring,你可以自己定義構(gòu)造初始化等等。
容器bean名稱:默認(rèn)就是對應(yīng)方法名(a)
建議使用場景:比如在引入的jar包里的對象,你想加入到Spring中,一般會用這個。還有就是你想定義類生成的具體過程,這個方式比較靈活。

@Configuration
public class AppConfiguration {
    @Bean
    public A a() {
        return new A("junmo", 27);
    }
}

@Import

說起這個注解之前請你一定看看官方的說明

/**
 * 用于導(dǎo)入一個或多個<em>組件類</em>,通常是{@link Configuration @Configuration}類。
 * 
 * <p>功能類似于Spring XML中的{@code <import/>}元素。
 * 允許導(dǎo)入{@code @Configuration}類、{@link ImportSelector}和
 * {@link ImportBeanDefinitionRegistrar}的實現(xiàn)類,以及普通的組件類(從4.2開始支持,類似于
 * {@link AnnotationConfigApplicationContext#register}方法的功能)。
 * 
 * <p>在導(dǎo)入的{@code @Configuration}類中定義的{@code @Bean}可以通過
 * {@link org.springframework.beans.factory.annotation.Autowired @Autowired}注解注入。
 * 開發(fā)者可以選擇直接注入Bean,也可以注入聲明該Bean的配置類的實例,后者便于在IDE中快速導(dǎo)航配置方法。
 * 
 * <p>該注解可以直接用在類上,也可以作為元注解被其他注解使用。
 * 
 * <p>如果需要導(dǎo)入XML或其他非{@code @Configuration}的資源,應(yīng)使用
 * {@link ImportResource @ImportResource}注解。
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
	/**
	 * 指定要導(dǎo)入的類,包括以下幾類:
	 * 1. 標(biāo)注為{@link Configuration @Configuration}的類。
	 * 2. 實現(xiàn)了{(lán)@link ImportSelector}接口的類。
	 * 3. 實現(xiàn)了{(lán)@link ImportBeanDefinitionRegistrar}接口的類。
	 * 4. 普通的組件類。
	 */
	Class<?>[] value();
}

1. @Import(簡單)

@Import({A.class, B.class})
@Configuration
public class App {
}

從這里示例上能看出來,用法比較簡單,感覺跟@Component一樣無腦快速。而且它支持批量哦!
容器bean名稱:默認(rèn)就是全類名(xxx.xxx.App)
建議使用場景: 這個注解就有說明,指示要導(dǎo)入的一個或多個組件類,批量簡單快速導(dǎo)入一堆對象,可以用這個。(前提是這個類不是你項目中的類,是從外邊引入的類,而且需要加入到 ioc 中,不然@Component也可以做到)
缺點:很明顯這個方式對于構(gòu)建復(fù)雜對象初始化不太適合,不如@Bean。

2. @Import+實現(xiàn)ImportSelector接口(這個 SpringBoot 瘋狂用它)

很明顯這個可以寫代碼在運行時自己定義加入。這樣的好處是我可以選擇哪些對象加入到 ioc 中,畢竟只認(rèn)最后的返回 String[].

@Import(MyImportSelector.class)
@Configuration
public class App {
}
public class MyImportSelector implements ImportSelector {
		@Override
		public String[] selectImports(AnnotationMetadata importingClassMetadata) {
			// importingClassMetadata:這個是目標(biāo)類上的注解, 就是上面 App 類上的所有注解(@Import, @Configuration)有什么用?能力有限, 暫時未知 haha
			// 這里可以擇別一些條件選擇性加載
			if(xxxxxxxxx) {
				return new String[]{"com.dao.daocloud.A", "com.dao.daocloud.B"};
			} else {
				return new String[]{"com.dao.daocloud.A", "com.dao.daocloud.C"};
			}
		}
	}
}

容器bean名稱:默認(rèn)就是全類名(xxx.xxx.App)
建議使用場景: 也支持批量,同時你的項目中需要澤別條件,選擇性的加載 bean,可以用這個。
缺點:很明顯這個方式對于構(gòu)建復(fù)雜對象初始化不太適合,不如@Bean,而且還要實現(xiàn)一個接口,比較繁瑣。

3. @Import+實現(xiàn)ImportBeanDefinitionRegistrar接口

這個最大的好處是可以拿到 ioc bean注冊器(BeanDefinitionRegistry),它的作用很多,也就是你可以為所欲為在程序中.

@Import(MyImportBeanDefinitionRegistrar.class)
@Configuration
public class App {
}
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
    	// 這個 A 就是你的對象類
        BeanDefinition aBeanDefinition = new RootBeanDefinition(A.class);
        registry.registerBeanDefinition("可以定義自己的bean名稱", aBeanDefinition);
    }
}

容器bean名稱:可以自己定義 bean 名稱
建議使用場景: 對比上面兩種,這個可以拿到BeanDefinitionRegistry,可以自己定義 bean 名稱,還可以做一些別的事.

FactoryBean(非注解)

從第一眼看上去,翻譯下就是工廠 bean,看意思就是知道這個方式可以來生產(chǎn)出 bean 對象,它其實就是用了一個載體來生產(chǎn) bean,它本身也是一個 bean,它的用法與上面幾種完全不一樣。形象舉個例子:這個就像是一個冰壺(FactoryBean)放了水(bean),冰壺可以倒出水。

@Component  // 當(dāng)然這里你也可以用 @Bean 把它加載到 ioc 中
public class AFactoryBean implements FactoryBean<A> {
    @Override
    public A getObject() throws Exception {
        // 這里感覺就和@Bean一樣,可以自己構(gòu)建自己的對象并且初始化.
        return new A("junmo", 27);
    }
    @Override
    public Class<?> getObjectType() {
        // 這個我就不理解了,為什么要提供這個?不是在 getObject 對象都能拿到,Class 信息還拿不到嗎,還要開發(fā)者必須重寫實現(xiàn)這個方法,不理解,不知道什么樣的場景會用到這個方法。
        return A.class;
    }
    @Override
    // 這個是設(shè)置單例還是多例的,不在本文討論范圍之內(nèi),但是你要知道它可以做到這個事情
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }
}

容器bean名稱:這個有點特殊。它的 bean 名稱在 ioc 容器中會是AFactoryBean,然后你拿到的對象類確會是 A.class。(很明顯它調(diào)用getObject方法給你生產(chǎn)對象了,也就是說它為什么叫FactoryBean的含義)
建議使用場景: 動態(tài)對象創(chuàng)建、根據(jù)條件生成不同 Bean、創(chuàng)建代理類、生成多實例或生命周期管理需求。但是我覺得與@Bean也沒多大區(qū)別。但是外面很多框架都用了這個方式來定義 bean。還是有個區(qū)別,因為它會調(diào)用 getObject方法來生產(chǎn)對象,這個可以在項目運行后也可以生效,可以動態(tài)改生成 bean 的方式。
另外說一句:如果你要獲取AFactoryBean本身對象,可以用在前面加"&"來獲取該對象,算了,這個不重要,一般不太會用到(從下面源碼中很好理解).

public interface BeanFactory {
	/**
	 * Used to dereference a {@link FactoryBean} instance and distinguish it from
	 * beans <i>created</i> by the FactoryBean. For example, if the bean named
	 * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
	 * will return the factory, not the instance returned by the factory.
	 */
	String FACTORY_BEAN_PREFIX = "&";
}

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

相關(guān)文章

  • Java正則表達(dá)式API邊界匹配

    Java正則表達(dá)式API邊界匹配

    這篇文章主要介紹了Java正則表達(dá)式API邊界匹配,文章圍繞主題展開相應(yīng)的相關(guān)資料,具有一定的參考價值,需要的朋友可以參考一下
    2022-06-06
  • Java正則表達(dá)式匹配不到結(jié)果的解決

    Java正則表達(dá)式匹配不到結(jié)果的解決

    這篇文章主要介紹了Java正則表達(dá)式匹配不到結(jié)果的解決,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • java通過模擬post方式提交表單實現(xiàn)圖片上傳功能實例

    java通過模擬post方式提交表單實現(xiàn)圖片上傳功能實例

    這篇文章主要介紹了java通過模擬post方式提交表單實現(xiàn)圖片上傳功能實例,涉及Java針對表單的提交操作響應(yīng)及文件傳輸?shù)南嚓P(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-11-11
  • 微信公眾平臺開發(fā)實戰(zhàn)Java版之微信獲取用戶基本信息

    微信公眾平臺開發(fā)實戰(zhàn)Java版之微信獲取用戶基本信息

    這篇文章主要介紹了微信公眾平臺開發(fā)實戰(zhàn)Java版之微信獲取用戶基本信息 的相關(guān)資料,需要的朋友可以參考下
    2015-12-12
  • Java中數(shù)字黑洞實現(xiàn)代碼

    Java中數(shù)字黑洞實現(xiàn)代碼

    這篇文章主要介紹了Java編程中如何實現(xiàn)數(shù)字黑洞算法游戲,其中涉及到了數(shù)組、scanner、if語句等Java編程的基礎(chǔ)知識,需要的朋友可以參考下
    2017-09-09
  • Maven插件docker-maven-plugin的使用

    Maven插件docker-maven-plugin的使用

    在我們持續(xù)集成過程中,項目工程一般使用 Maven 編譯打包,然后生成鏡像,docker-maven-plugin 插件就是為了幫助我們在Maven工程中,通過簡單的配置,自動生成鏡像并推送到倉庫中。感興趣的可以了解一下
    2021-06-06
  • java中如何使用BufferedImage判斷圖像通道順序并轉(zhuǎn)RGB/BGR

    java中如何使用BufferedImage判斷圖像通道順序并轉(zhuǎn)RGB/BGR

    這篇文章主要介紹了java中如何BufferedImage判斷圖像通道順序并轉(zhuǎn)RGB/BGR的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 簡單了解Java日志脫敏框架sensitive

    簡單了解Java日志脫敏框架sensitive

    這篇文章主要介紹了簡單了解Java日志脫敏框架sensitive,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • IDEA新建JAVA項目簡單圖文教程

    IDEA新建JAVA項目簡單圖文教程

    這篇文章主要給大家介紹了關(guān)于IDEA新建JAVA項目的相關(guān)資料,IDEA是現(xiàn)在java中最為常用的編譯器,所以如何使用IDEA來創(chuàng)建java項目呢,這里給大家總結(jié)下,需要的朋友可以參考下
    2023-08-08
  • 基于java中cas實現(xiàn)的探索

    基于java中cas實現(xiàn)的探索

    這篇文章主要介紹了java中cas實現(xiàn)的探索,基于很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12

最新評論