亲宝软件园·资讯

展开

Java DefaultListableBeanFactory接口超详细介绍

氵奄不死的鱼 人气:0

前言

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

加载全部内容

相关教程
猜你喜欢
用户评论