• DefaultListableBeanFactory接口总结


    前言

    本文,对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");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    接口

    
    public interface AliasRegistry {
    
    	void registerAlias(String name, String alias);
    
    
    	void removeAlias(String alias);
    
    	boolean isAlias(String name);
    
    
    	String[] getAliases(String name);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    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 + "'");
    				}
    			}
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    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();
    
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

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

    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);
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注册单例接口
    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);
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    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);
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    如果直接把生成好的实例,那么直接放入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);
    			}
    		}
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    三级缓存发挥作用
    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;
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    分别尝试从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;
    	}
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    private Object doGetObjectFromFactoryBean(FactoryBean<?> factory, String beanName) throws BeanCreationException {
    		Object object;
        ······················
    		object = factory.getObject();
    	·····················
    		return object;
    	}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    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);
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    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体系目前的所有方法。

  • 相关阅读:
    ThingsBoard物联网网关在智慧城市数据采集中的应用
    程序员竟然还有职业规划手册?
    第二十三章 Classes - 属性
    antd-design的modal结合form表单传值
    JDBC中setTransactionIsolation
    微信小程序使用npm教程
    做题日记 之 pairs(HDU-5178)
    W10安装Cuda和cuDNN环境
    【以图搜图】GPU&NPU适配万物识别模型和Milvus向量数据库
    JVM系列:JDK、JRE、JVM 的关系
  • 原文地址:https://blog.csdn.net/qq_37436172/article/details/127755811