Java DefaultListableBeanFactory接口超详细介绍

 更新时间:2022年11月18日 09:19:02   作者:氵奄不死的鱼  
这篇文章主要介绍了Java DefaultListableBeanFactory接口,DefaultListableBeanFactory是整个bean加载的核心部分,是Spring注册机加载bean的默认实现

前言

本文,对bean工厂的接口做分析梳理具体实现不研究

默认的工厂实现为DefaultListableBeanFactory

类图

AliasRegistry

功能是实现对一个bean注册多个不同的别名

例如

@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个api,分别是注册alias、删除alias、获取alias、判断指定名称是否是alias。AliasRegistry该接口层次在spring中非常高,因而是非常基础的一个接口。继承此接口需要实现别名

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中维护aliasMap

如果存在重名,判断是否允许覆盖

判断循环引用,如果存在 alias, name和name, alias同时存在,抛出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();
}

注册获取单例接口具体实现

实现类

DefaultSingletonBeanRegistry

先看大名鼎鼎的三级缓存

        /*存放已经完成创建的bean  */
	private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
	/** 存放存放生成bean的工厂,生成bean后先放入earlySingletonObjects */
	private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    /*存放提前暴露的bean实例,还未完全初始化*/
	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);
		}
	}

如果直接把生成好的实例,那么直接放入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);
			}
		}
	}

三级缓存发挥作用

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中获取实例

如都获取不到锁住singletonObjects再次读一遍,如果没有其他线程修改,通过singletonFactory生成对象,放入

earlySingletonObjects并从singletonFactories中移除

FactoryBeanRegistrySupport

提供对factoryBean接口的支持。

FactoryBean是什么?

FactoryBean接口的作用在bean工工厂上。是对bean进行自定义实例化,可以认为是方法工厂模式。spring默认的工厂,生产所有的实例的方式都相同,而FactoryBean.getObject可以自定义这个方式

FactoryBean

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

关键方法,调用FactoryBean的getObject生成bean实例

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

AbstractBeanFactory

来到AbstractBeanFactory。基本没有扩展新的功能接口,这个类的主要对继承的接口有了个大概的实现,整个工厂大部分实现都在这里

AbstractAutowireCapableBeanFactory

AbstractAutowireCapableBeanFactory在AbstractBeanFactory的基础上又扩展了,Autowire功能

这个工厂接口继承自BeanFacotory,它扩展了自动装配的功能,根据类定义BeanDefinition装配Bean、执行前、后处理器等。

AutowireCapableBeanFactory的具体实现都在AbstractAutowireCapableBeanFactory

例如org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#autowire进行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个忽略自动装配的的方法。

2、1个注册一个可分解依赖的方法。

3、1个判断指定的Bean是否有资格作为自动装配的候选者的方法。

4、1个根据指定bean名,返回注册的Bean定义的方法。

5、2个冻结所有的Bean配置相关的方法。

6、1个使所有的非延迟加载的单例类都实例化的方法(preInstantiateSingletons)。

总结:工厂接口ConfigurableListableBeanFactory同时继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory,扩展之后,加上自有的这8个方法,这个工厂接口总共有83个方法,实在是巨大到不行了。这个工厂接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法。

到此这篇关于Java DefaultListableBeanFactory接口超详细介绍的文章就介绍到这了,更多相关Java DefaultListableBeanFactory内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot中如何使用openfeign进行接口调用

    springboot中如何使用openfeign进行接口调用

    这篇文章主要介绍了springboot中如何使用openfeign进行接口调用问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • Java源码解析HashMap的keySet()方法

    Java源码解析HashMap的keySet()方法

    今天小编就为大家分享一篇关于Java源码解析HashMap的keySet()方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • SpringBoot Security安装配置及Thymeleaf整合

    SpringBoot Security安装配置及Thymeleaf整合

    这篇文章主要介绍了SpringBoot Security安装配置及Thymeleaf整合,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-12-12
  • RocketMQ消息中间件超详细解读

    RocketMQ消息中间件超详细解读

    这篇文章主要介绍了RocketMQ消息中间件超详细解读,RocketMQ作为一款纯java、分布式、队列模型的开源消息中间件,支持事务消息、顺序消息、批量消息、定时消息、消息回溯等,本文就来详细解读一下,需要的朋友可以参考下
    2023-05-05
  • Java精品项目瑞吉外卖之员工新增篇

    Java精品项目瑞吉外卖之员工新增篇

    这篇文章主要为大家详细介绍了java精品项目-瑞吉外卖订餐系统,此项目过大,分为多章独立讲解,本篇内容为新增员工功能的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-05-05
  • Java中动态地改变数组长度及数组转Map的代码实例分享

    Java中动态地改变数组长度及数组转Map的代码实例分享

    这篇文章主要介绍了Java中动态地改变数组长度及数组转map的代码分享,其中转Map利用到了java.util.Map接口,需要的朋友可以参考下
    2016-03-03
  • Flowable整合SpringBoot实现的示例代码

    Flowable整合SpringBoot实现的示例代码

    本文详细介绍了如何在SpringBoot项目中整合Flowable进行工作流管理,包括依赖引入、流程部署与启动、表结构、流程挂起和激活以及任务分配等关键操作,具有一定的参考价值,感兴趣的可以了解一下
    2024-09-09
  • SpringBoot添加自定义拦截器的实现代码

    SpringBoot添加自定义拦截器的实现代码

    这篇文章主要介绍了SpringBoot添加自定义拦截器的实现代码,非常不错,具有一定的参考借鉴价值,需要的朋友可以参考下
    2018-09-09
  • Java轻松入门冒泡 选择 插入 希尔 归并排序算法

    Java轻松入门冒泡 选择 插入 希尔 归并排序算法

    这篇文章主要介绍了Java常用的排序算法及代码实现,在Java开发中,对排序的应用需要熟练的掌握,这样才能够确保Java学习时候能够有扎实的基础能力。那Java有哪些排序算法呢?本文小编就来详细说说Java常见的排序算法,需要的朋友可以参考一下
    2022-02-02
  • Properties操作如何保存到属性文件

    Properties操作如何保存到属性文件

    这篇文章主要介绍了Properties操作保存到属性文件的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2023-06-06

最新评论