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

Spring中的FactoryBean實現原理詳解

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

1、概述

spring中有兩種類型的Bean:

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

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

2、詳述

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

那么FactoryBean呢?

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

FactoryBean接口提供的方法如下:

public interface FactoryBean<T> {
	//獲取FactoryBean初始化的Bean實例
	T getObject() throws Exception;
	//獲取Bean實例的類型
	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();  
	}  
}

運行結果

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

4、實現原理

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

getBean獲取bean

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

doGetBean中獲取bean實例

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實例是普通的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;
		.........//省略部分代碼
		//調用Factory的getObject方法
		object = factory.getObject();
		.........//省略部分代碼
		return object;
	}

總結

Spring對FactoryBean的實現機制是當你獲取一個Bean時,如果獲取的Bean的類型是FactoryBean,并且其name中并沒有&則調用bean的getObject方法獲取FactoryBean實現類中提供bean,否則就是直接返回普通的bean類型。

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

相關文章

  • Java fastjson解析json字符串實現過程解析

    Java fastjson解析json字符串實現過程解析

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

    Java synchronized與CAS使用方式詳解

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

    java json與map互相轉換的示例

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

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

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

    springboot項目docker分層構建的配置方式

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

    Java?Excel?Poi字體顏色自定義設置代碼

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

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

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

    MyBatis傳入參數的實例代碼

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

    Java如果通過jdbc操作連接oracle數據庫

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

    Java OpenCV利用KNN算法實現圖像背景移除

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

最新評論