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

Java DefaultListableBeanFactory接口超詳細(xì)介紹

 更新時(shí)間:2022年11月18日 09:19:02   作者:氵奄不死的魚  
這篇文章主要介紹了Java DefaultListableBeanFactory接口,DefaultListableBeanFactory是整個(gè)bean加載的核心部分,是Spring注冊機(jī)加載bean的默認(rèn)實(shí)現(xiàn)

前言

本文,對bean工廠的接口做分析梳理具體實(shí)現(xiàn)不研究

默認(rèn)的工廠實(shí)現(xiàn)為DefaultListableBeanFactory

類圖

AliasRegistry

功能是實(shí)現(xiàn)對一個(gè)bean注冊多個(gè)不同的別名

例如

@Component
public class AliasConfiguration implements BeanFactoryPostProcessor {
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        beanFactory.registerAlias("originalBeanName", "newAlias");
        beanFactory.registerAlias("originalBeanName", "newAlias2");
        beanFactory.registerAlias("otherOriginalBeanName", "newAlias3");
    }
}

接口

public interface AliasRegistry {
	void registerAlias(String name, String alias);
	void removeAlias(String alias);
	boolean isAlias(String name);
	String[] getAliases(String name);
}

AliasRegistry接口是alias注冊管理接口,支持4個(gè)api,分別是注冊alias、刪除alias、獲取alias、判斷指定名稱是否是alias。AliasRegistry該接口層次在spring中非常高,因而是非?;A(chǔ)的一個(gè)接口。繼承此接口需要實(shí)現(xiàn)別名

SimpleAliasRegistry

@Override
	public void registerAlias(String name, String alias) {
		Assert.hasText(name, "'name' must not be empty");
		Assert.hasText(alias, "'alias' must not be empty");
		synchronized (this.aliasMap) {
			if (alias.equals(name)) {
				this.aliasMap.remove(alias);
				if (logger.isDebugEnabled()) {
					logger.debug("Alias definition '" + alias + "' ignored since it points to same name");
				}
			}
			else {
				String registeredName = this.aliasMap.get(alias);
				if (registeredName != null) {
					if (registeredName.equals(name)) {
						// An existing alias - no need to re-register
						return;
					}
					if (!allowAliasOverriding()) {
						throw new IllegalStateException("Cannot define alias '" + alias + "' for name '" +
								name + "': It is already registered for name '" + registeredName + "'.");
					}
					if (logger.isDebugEnabled()) {
						logger.debug("Overriding alias '" + alias + "' definition for registered name '" +
								registeredName + "' with new target name '" + name + "'");
					}
				}
				checkForAliasCircle(name, alias);
				this.aliasMap.put(alias, name);
				if (logger.isTraceEnabled()) {
					logger.trace("Alias definition '" + alias + "' registered for name '" + name + "'");
				}
			}
		}
	}

SimpleAliasRegistry中維護(hù)aliasMap

如果存在重名,判斷是否允許覆蓋

判斷循環(huán)引用,如果存在 alias, name和name, alias同時(shí)存在,拋出Circular reference異常

SingletonBeanRegistry

public interface SingletonBeanRegistry {
	void registerSingleton(String beanName, Object singletonObject);
	@Nullable
	Object getSingleton(String beanName);
	boolean containsSingleton(String beanName);
	String[] getSingletonNames();
	int getSingletonCount();
	Object getSingletonMutex();
}

注冊獲取單例接口具體實(shí)現(xiàn)

實(shí)現(xiàn)類

DefaultSingletonBeanRegistry

先看大名鼎鼎的三級緩存

        /*存放已經(jīng)完成創(chuàng)建的bean  */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	/** 存放存放生成bean的工廠,生成bean后先放入earlySingletonObjects */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    /*存放提前暴露的bean實(shí)例,還未完全初始化*/
	private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);

注冊單例接口

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#registerSingleton

@Override
	public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException {
		Assert.notNull(beanName, "Bean name must not be null");
		Assert.notNull(singletonObject, "Singleton object must not be null");
		synchronized (this.singletonObjects) {
			Object oldObject = this.singletonObjects.get(beanName);
			if (oldObject != null) {
				throw new IllegalStateException("Could not register object [" + singletonObject +
						"] under bean name '" + beanName + "': there is already object [" + oldObject + "] bound");
			}
			addSingleton(beanName, singletonObject);
		}
	}
protected void addSingleton(String beanName, Object singletonObject) {
		synchronized (this.singletonObjects) {
			this.singletonObjects.put(beanName, singletonObject);
			this.singletonFactories.remove(beanName);
			this.earlySingletonObjects.remove(beanName);
			this.registeredSingletons.add(beanName);
		}
	}

如果直接把生成好的實(shí)例,那么直接放入singletonObjects中,并且name放入registeredSingletons

如果需要提交暴露

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
		Assert.notNull(singletonFactory, "Singleton factory must not be null");
		synchronized (this.singletonObjects) {
			if (!this.singletonObjects.containsKey(beanName)) {
				this.singletonFactories.put(beanName, singletonFactory);
				this.earlySingletonObjects.remove(beanName);
				this.registeredSingletons.add(beanName);
			}
		}
	}

三級緩存發(fā)揮作用

org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, boolean)

@Nullable
	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
		// Quick check for existing instance without full singleton lock
		Object singletonObject = this.singletonObjects.get(beanName);
		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
			singletonObject = this.earlySingletonObjects.get(beanName);
			if (singletonObject == null && allowEarlyReference) {
				synchronized (this.singletonObjects) {
					// Consistent creation of early reference within full singleton lock
					singletonObject = this.singletonObjects.get(beanName);
					if (singletonObject == null) {
						singletonObject = this.earlySingletonObjects.get(beanName);
						if (singletonObject == null) {
							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
							if (singletonFactory != null) {
								singletonObject = singletonFactory.getObject();
								this.earlySingletonObjects.put(beanName, singletonObject);
								this.singletonFactories.remove(beanName);
							}
						}
					}
				}
			}
		}
		return singletonObject;
	}

分別嘗試從singletonObjects和earlySingletonObjects中獲取實(shí)例

如都獲取不到鎖住singletonObjects再次讀一遍,如果沒有其他線程修改,通過singletonFactory生成對象,放入

earlySingletonObjects并從singletonFactories中移除

FactoryBeanRegistrySupport

提供對factoryBean接口的支持。

FactoryBean是什么?

FactoryBean接口的作用在bean工工廠上。是對bean進(jìn)行自定義實(shí)例化,可以認(rèn)為是方法工廠模式。spring默認(rèn)的工廠,生產(chǎn)所有的實(shí)例的方式都相同,而FactoryBean.getObject可以自定義這個(gè)方式

FactoryBean

public interface FactoryBean<T> {
	String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
	@Nullable
	T getObject() throws Exception;
	@Nullable
	Class<?> getObjectType();
	default boolean isSingleton() {
		return true;
	}
}

關(guān)鍵方法,調(diào)用FactoryBean的getObject生成bean實(shí)例

private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
		Object object;
    ······················
		object = factory.getObject();
	·····················
		return object;
	}

AbstractBeanFactory

來到AbstractBeanFactory?;緵]有擴(kuò)展新的功能接口,這個(gè)類的主要對繼承的接口有了個(gè)大概的實(shí)現(xiàn),整個(gè)工廠大部分實(shí)現(xiàn)都在這里

AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory在AbstractBeanFactory的基礎(chǔ)上又?jǐn)U展了,Autowire功能

這個(gè)工廠接口繼承自BeanFacotory,它擴(kuò)展了自動裝配的功能,根據(jù)類定義BeanDefinition裝配Bean、執(zhí)行前、后處理器等。

AutowireCapableBeanFactory的具體實(shí)現(xiàn)都在AbstractAutowireCapableBeanFactory

例如org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowire進(jìn)行bean的注入

BeanDefinitionRegistry

BeanDefinition的一些操作接口

public interface BeanDefinitionRegistry extends AliasRegistry {
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	boolean containsBeanDefinition(String beanName);
	String[] getBeanDefinitionNames();
	int getBeanDefinitionCount();
	boolean isBeanNameInUse(String beanName);
}

ConfigurableListableBeanFactory

ConfigurableListableBeanFactory具體:

1、2個(gè)忽略自動裝配的的方法。

2、1個(gè)注冊一個(gè)可分解依賴的方法。

3、1個(gè)判斷指定的Bean是否有資格作為自動裝配的候選者的方法。

4、1個(gè)根據(jù)指定bean名,返回注冊的Bean定義的方法。

5、2個(gè)凍結(jié)所有的Bean配置相關(guān)的方法。

6、1個(gè)使所有的非延遲加載的單例類都實(shí)例化的方法(preInstantiateSingletons)。

總結(jié):工廠接口ConfigurableListableBeanFactory同時(shí)繼承了3個(gè)接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,擴(kuò)展之后,加上自有的這8個(gè)方法,這個(gè)工廠接口總共有83個(gè)方法,實(shí)在是巨大到不行了。這個(gè)工廠接口的自有方法總體上只是對父類接口功能的補(bǔ)充,包含了BeanFactory體系目前的所有方法。

到此這篇關(guān)于Java DefaultListableBeanFactory接口超詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Java DefaultListableBeanFactory內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringBoot實(shí)現(xiàn)WebSocket即時(shí)通訊的示例代碼

    SpringBoot實(shí)現(xiàn)WebSocket即時(shí)通訊的示例代碼

    本文主要介紹了SpringBoot實(shí)現(xiàn)WebSocket即時(shí)通訊的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • mybatis使用foreach踩坑及解決

    mybatis使用foreach踩坑及解決

    這篇文章主要介紹了mybatis使用foreach踩坑及解決,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • 解決常見的Eclipse SVN插件報(bào)錯方法詳解

    解決常見的Eclipse SVN插件報(bào)錯方法詳解

    本篇文章是對常見的Eclipse SVN插件報(bào)錯方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-05-05
  • Java中@Autowired和@Resource區(qū)別

    Java中@Autowired和@Resource區(qū)別

    本文主要介紹了Java中@Autowired和@Resource區(qū)別,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • Java語言實(shí)現(xiàn)快速冪取模算法詳解

    Java語言實(shí)現(xiàn)快速冪取模算法詳解

    這篇文章主要介紹了Java語言實(shí)現(xiàn)快速冪取模算法詳解,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 解決java.lang.NullPointerException報(bào)錯以及分析出現(xiàn)的幾種原因

    解決java.lang.NullPointerException報(bào)錯以及分析出現(xiàn)的幾種原因

    這篇文章介紹了解決java.lang.NullPointerException報(bào)錯的方法,以及分析出現(xiàn)的幾種原因。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-12-12
  • 深入了解java中的逃逸分析

    深入了解java中的逃逸分析

    這篇文章主要介紹了深入了解java中的逃逸分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Java編程用棧來求解漢諾塔問題的代碼實(shí)例(非遞歸)

    Java編程用棧來求解漢諾塔問題的代碼實(shí)例(非遞歸)

    這篇文章主要介紹了Java編程用棧來求解漢諾塔問題的代碼實(shí)例(非遞歸),具有一定參考價(jià)值,這里給大家分享下,供朋友們參考。
    2017-10-10
  • Java 垃圾回收機(jī)制詳解(動力節(jié)點(diǎn)Java學(xué)院整理)

    Java 垃圾回收機(jī)制詳解(動力節(jié)點(diǎn)Java學(xué)院整理)

    在系統(tǒng)運(yùn)行過程中,會產(chǎn)生一些無用的對象,這些對象占據(jù)著一定的內(nèi)存,如果不對這些對象清理回收無用對象的內(nèi)存,可能會導(dǎo)致內(nèi)存的耗盡,所以垃圾回收機(jī)制回收的是內(nèi)存。下面通過本文給大家詳細(xì)介紹java垃圾回收機(jī)制,一起學(xué)習(xí)吧
    2017-02-02
  • 解決fastjson泛型轉(zhuǎn)換報(bào)錯的解決方法

    解決fastjson泛型轉(zhuǎn)換報(bào)錯的解決方法

    這篇文章主要介紹了解決fastjson泛型轉(zhuǎn)換報(bào)錯的解決方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-11-11

最新評論