博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码分析之核心容器类图
阅读量:2402 次
发布时间:2019-05-10

本文共 5046 字,大约阅读时间需要 16 分钟。

1.IOC容器的祖先----BeanFactory接口

BeanFactory是Spring IOC中重要的一个顶层接口。它是工厂模式的产物,里面定义了一些对bean操作的方法。在其子接口进行了扩展。它有三个重要的子接口分别是ListableBeanFactory、HierarchicalBeanFactory、AutowireCapableBeanFactory。它们最终都由一个子类进行实现,就是DefaultListableBeanFactory,它实现了所有的接口。

public interface BeanFactory {	//对FactoryBean的转义定义,因为如果使用bean的名字检索FactoryBean得到的对象是工厂生成的对象,	//如果需要得到工厂本身,需要转义	String FACTORY_BEAN_PREFIX = "&";	//根据bean的名字,获取在IOC容器中得到bean实例	Object getBean(String name) throws BeansException;	//根据bean的名字和Class类型来得到bean实例,增加了类型安全验证机制。	
T getBean(String name, @Nullable Class
requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException;
T getBean(Class
requiredType) throws BeansException;
T getBean(Class
requiredType, Object... args) throws BeansException; //提供对bean的检索,看看是否在IOC容器有这个名字的bean boolean containsBean(String name); //根据bean名字得到bean实例,并同时判断这个bean是不是单例 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, @Nullable Class
typeToMatch) throws NoSuchBeanDefinitionException; //得到bean实例的Class类型 @Nullable Class
getType(String name) throws NoSuchBeanDefinitionException; //得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String[] getAliases(String name);}

2.IOC容器的集大成者----DefaultListableBeanFactory

如果说BeanFactory接口是IOC容器的祖先,那么DefaultListableBeanFactory就是IOC容器的集大成者。它是一个成熟完善的bean  factory。为什么它要实现所有接口呢?阅读Spring源码注释我们知道,每个接口都有它使用的场合,主要是为了区分在Spring内部操作过程中对象的传递和转化,对对象的数据访问所做的限制。它里面有个重要的方法registerBeanDefinition(),它是向容器注册解析好的BeanDefinition。

//向IOC容器注册解析的BeanDefiniton	@Override	public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)			throws BeanDefinitionStoreException {		Assert.hasText(beanName, "Bean name must not be empty");		Assert.notNull(beanDefinition, "BeanDefinition must not be null");		//校验解析的BeanDefiniton		if (beanDefinition instanceof AbstractBeanDefinition) {			try {				((AbstractBeanDefinition) beanDefinition).validate();			}			catch (BeanDefinitionValidationException ex) {				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,						"Validation of bean definition failed", ex);			}		}		BeanDefinition oldBeanDefinition;		oldBeanDefinition = this.beanDefinitionMap.get(beanName);		if (oldBeanDefinition != null) {			if (!isAllowBeanDefinitionOverriding()) {				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,						"Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +						"': There is already [" + oldBeanDefinition + "] bound.");			}			else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE				if (this.logger.isWarnEnabled()) {					this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +							"' with a framework-generated bean definition: replacing [" +							oldBeanDefinition + "] with [" + beanDefinition + "]");				}			}			else if (!beanDefinition.equals(oldBeanDefinition)) {				if (this.logger.isInfoEnabled()) {					this.logger.info("Overriding bean definition for bean '" + beanName +							"' with a different definition: replacing [" + oldBeanDefinition +							"] with [" + beanDefinition + "]");				}			}			else {				if (this.logger.isDebugEnabled()) {					this.logger.debug("Overriding bean definition for bean '" + beanName +							"' with an equivalent definition: replacing [" + oldBeanDefinition +							"] with [" + beanDefinition + "]");				}			}			this.beanDefinitionMap.put(beanName, beanDefinition);		}		else {			if (hasBeanCreationStarted()) {				// Cannot modify startup-time collection elements anymore (for stable iteration)				//注册的过程中需要线程同步,以保证数据的一致性				synchronized (this.beanDefinitionMap) {					this.beanDefinitionMap.put(beanName, beanDefinition);					List
updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { Set
updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } //检查是否有同名的BeanDefinition已经在IOC容器中注册 if (oldBeanDefinition != null || containsSingleton(beanName)) { //重置所有已经注册过的BeanDefinition的缓存 resetBeanDefinition(beanName); } }

类层级关系图

-----------明天继续写---------------------

 

转载地址:http://gjpob.baihongyu.com/

你可能感兴趣的文章
kudzu命令查看及设置网卡等硬件信息
查看>>
用RMAN迁移文件到ASM或从ASM迁出
查看>>
421 Message temporarily deferred (from yahoo)
查看>>
elicpse如何查看jdk源码
查看>>
RabbitMQ与SpringMVC集成并实现发送消息和接收消息(持久化)方案二
查看>>
linux系统启动过程
查看>>
mysql之分区表小结1
查看>>
InnoDBd的auto_increment以及innodb_autoinc_lock_mode
查看>>
linux 2.6的IO调度算法
查看>>
innodb master线程的工作机制
查看>>
存储知识小结
查看>>
mysql常用函数
查看>>
温习tcp知识
查看>>
mysql用于分配内存的参数
查看>>
[转载]移动开发谁领风骚 J2ME开发工具面面观
查看>>
[转载]Java嵌入式开发之四-J2ME与MIDP开发
查看>>
java实现屏幕取色
查看>>
[转载]项目经验二则:读取war包中的文件及Ant使用中的OutOfMemoryError解决
查看>>
[转载]实例讲解配置之——TOMCAT集群配置
查看>>
[转载]保护XML文档的工具
查看>>