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

Spring中的FactoryBean實(shí)現(xiàn)原理詳解

 更新時間:2024年02月14日 08:50:49   作者:軍偉@  
這篇文章主要介紹了Spring中的FactoryBean實(shí)現(xiàn)原理詳解,spring中有兩種類型的Bean,一種是普通的JavaBean,另一種就是工廠Bean(FactoryBean),這兩種Bean都受Spring的IoC容器管理,但它們之間卻有一些區(qū)別,需要的朋友可以參考下

1、概述

spring中有兩種類型的Bean:

  1. 一種是普通的JavaBean;
  2. 另一種就是工廠Bean(FactoryBean)

這兩種Bean都受Spring的IoC容器管理,但它們之間卻有一些區(qū)別。

2、詳述

普通的JavaBean不再多說,我們將其定義好,然后在配置文件中定義并配置其依賴關(guān)系,就可以通過IoC容器的getBean獲取到。

那么FactoryBean呢?

FactoryBean跟普通Bean不同,它是實(shí)現(xiàn)了FactoryBean<T>接口的Bean,通過BeanFactory類的getBean方法直接獲取到的并不是該FactoryBean的實(shí)例,而是該FactoryBean中方法getObject返回的對象。但我們可以通過其它途徑獲取到該FactoryBean的實(shí)例,方法就是在通過getBean方法獲取實(shí)例時在參數(shù)name前面加上“&”符號即可。

FactoryBean接口提供的方法如下:

public interface FactoryBean<T> {
	//獲取FactoryBean初始化的Bean實(shí)例
	T getObject() throws Exception;
	//獲取Bean實(shí)例的類型
	Class<?> getObjectType();
	//判斷是否是單例模式
	boolean isSingleton();
}

3、示例

創(chuàng)建MyFactoryBean

public class MyFactoryBean implements FactoryBean<Date>,BeanNameAware {  
    private String name;  
    @Override  
    public Date getObject() throws Exception {  
        return new Date();  
    }  
    @Override  
    public Class<?> getObjectType() {  
        return Date.class;  
    }  
    @Override  
    public boolean isSingleton() {  
        return false;  
    }  
    public void sayName() {  
        System.out.println("My name is " + this.name);  
    }  
    @Override  
    public void setBeanName(String name) {  
        this.name = name;  
    }  
}  

在Spring的配置文件ApplicationContext.xml中注入MyFactoryBean

<bean id ="myFactoryBean" class="com.xxxx.MyFactoryBean"></bean>

測試代碼

public class MainFactoryBean {
 
	@SuppressWarnings("resource")
	public static void main(String [] args){  
		ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml");
	    Date now = (Date) appCtx.getBean("myFactoryBean");  
	    System.out.println(now);  
	    MyFactoryBean factoryBean = (MyFactoryBean) appCtx.getBean("&myFactoryBean");  
	    factoryBean.sayName();  
	}  
}

運(yùn)行結(jié)果

通過myFactoryBean名稱獲取到的Bean是Date對象實(shí)例,通過&myFactoryBean獲取到的是MyFactoryBean對象實(shí)例。

4、實(shí)現(xiàn)原理

我們來看一下執(zhí)行Date now = (Date) appCtx.getBean("myFactoryBean");  時會做的處理操作。 AbstractBeanFactory中會進(jìn)行一系列的操作。

getBean獲取bean

@Override
	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

doGetBean中獲取bean實(shí)例

protected <T> T doGetBean(
			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
			throws BeansException {
		.........//省略部分代碼
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		.........//省略部分代碼
		return (T) bean;
	}

getObjectForBeanInstance中會選擇bean實(shí)例是普通的Bean還是FactoryBean,同時通過判斷name中是否有&來選擇判斷是或者FactoryBean還是其getObject方法中獲取的bean

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
		.........//省略部分代碼
		//判斷bean類型是否是FactoryBean,或者name是否是以&開頭,如果是則直接返回
		if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}
		//如果是則從getObjectFromFactoryBean中獲取
		if (object == null) {
			// Return bean instance from factory.
			FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
			if (mbd == null && containsBeanDefinition(beanName)) {
				mbd = getMergedLocalBeanDefinition(beanName);
			}
			boolean synthetic = (mbd != null && mbd.isSynthetic());
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

getObjectFromFactoryBean接下來會執(zhí)行FactoryBean的getObject方法獲取bean了。

protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
		.........//省略部分代碼				
		Object object = doGetObjectFromFactoryBean(factory, beanName);
		.........//省略部分代碼
		return object;
	}
	
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
			throws BeanCreationException {
		Object object;
		.........//省略部分代碼
		//調(diào)用Factory的getObject方法
		object = factory.getObject();
		.........//省略部分代碼
		return object;
	}

總結(jié)

Spring對FactoryBean的實(shí)現(xiàn)機(jī)制是當(dāng)你獲取一個Bean時,如果獲取的Bean的類型是FactoryBean,并且其name中并沒有&則調(diào)用bean的getObject方法獲取FactoryBean實(shí)現(xiàn)類中提供bean,否則就是直接返回普通的bean類型。

到此這篇關(guān)于Spring中的FactoryBean實(shí)現(xiàn)原理詳解的文章就介紹到這了,更多相關(guān)FactoryBean實(shí)現(xiàn)原理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java fastjson解析json字符串實(shí)現(xiàn)過程解析

    Java fastjson解析json字符串實(shí)現(xiàn)過程解析

    這篇文章主要介紹了Java fastjson解析json字符串實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • Java synchronized與CAS使用方式詳解

    Java synchronized與CAS使用方式詳解

    提到Java的知識點(diǎn)一定會有多線程,JDK版本不斷的更迭很多新的概念和方法也都響應(yīng)提出,但是多線程和線程安全一直是一個重要的關(guān)注點(diǎn)。比如說我們一入門就學(xué)習(xí)的synchronized怎么個實(shí)現(xiàn)和原理,還有總是被提到的CAS是啥,他和synchronized關(guān)系是啥?請往下看
    2023-01-01
  • java json與map互相轉(zhuǎn)換的示例

    java json與map互相轉(zhuǎn)換的示例

    這篇文章主要介紹了java json與map互相轉(zhuǎn)換的示例,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-10-10
  • Spring中Bean的作用域與生命周期詳解

    Spring中Bean的作用域與生命周期詳解

    這篇文章主要給大家介紹了Spring中Bean的生命周期和作用域及實(shí)現(xiàn)方式的相關(guān)資料,文中介紹的非常詳細(xì),對大家具有一定的參考價值,需要的朋友們下面來一起看看吧
    2021-08-08
  • springboot項(xiàng)目docker分層構(gòu)建的配置方式

    springboot項(xiàng)目docker分層構(gòu)建的配置方式

    在使用dockerfile構(gòu)建springboot項(xiàng)目時,速度較慢,用時比較長,為了加快構(gòu)建docker鏡像的速度,采用分層構(gòu)建的方式,這篇文章主要介紹了springboot項(xiàng)目docker分層構(gòu)建,需要的朋友可以參考下
    2024-03-03
  • Java?Excel?Poi字體顏色自定義設(shè)置代碼

    Java?Excel?Poi字體顏色自定義設(shè)置代碼

    最近項(xiàng)目使用POI按模板導(dǎo)出Excel,需要設(shè)置單元格的字體為紅色,下面這篇文章主要給大家介紹了關(guān)于Java?Excel?Poi字體顏色自定義設(shè)置的相關(guān)資料,需要的朋友可以參考下
    2024-01-01
  • Spring Boot讀取配置屬性常用方法解析

    Spring Boot讀取配置屬性常用方法解析

    這篇文章主要介紹了Spring Boot讀取配置屬性常用方法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • MyBatis傳入?yún)?shù)的實(shí)例代碼

    MyBatis傳入?yún)?shù)的實(shí)例代碼

    這篇文章主要介紹了MyBatis傳入?yún)?shù)的實(shí)例代碼的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-06-06
  • Java如果通過jdbc操作連接oracle數(shù)據(jù)庫

    Java如果通過jdbc操作連接oracle數(shù)據(jù)庫

    這篇文章主要介紹了Java如果通過jdbc操作連接oracle數(shù)據(jù)庫,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-09-09
  • Java OpenCV利用KNN算法實(shí)現(xiàn)圖像背景移除

    Java OpenCV利用KNN算法實(shí)現(xiàn)圖像背景移除

    這篇文章主要為大家介紹了Java OpenCV利用K最鄰近(KNN,K-NearestNeighbor)分類算法實(shí)現(xiàn)圖像背景移除的示例代碼,需要的可以參考一下
    2022-01-01

最新評論