您现在的位置是:首页 >技术杂谈 >Spring源码-浅识BeanFactory网站首页技术杂谈

Spring源码-浅识BeanFactory

隙间光点 2024-06-14 17:19:22
简介Spring源码-浅识BeanFactory

Spring是如何启动的

在SpringBoot出现之前,我们使用Spring需要以配置文件的方式进行启动.如果使用XML文件配置.则通过XmlWebApplicationContext.java进行启动.常应用在Web项目的开发中.
以此为例,通过阅读源码发现和XmlWebApplicationContext.java"平级"的类如下所示
ApplicationContext.png
由此我们可以知道ApplicationContext遵循ApplicationContext.java的定义.如下所示其父依赖结构
image.png
此时我们可以看到最顶层的接口BeanFactory.java

揭开BeanFactory的面纱

BeanFactory本质是一个赤裸裸的接口

忽略掉繁杂的定义,BeanFactory.java 本质上就是一个接口——其中定义了一些方法。如下图示——并没有太多复杂的东西。
image.png

从官方注释提炼重要信息

  • The root interface for accessing a Spring bean container

为什么这样讲——我们需要获得一个bean的话,必须通过getBean方法,而getBean方法在该接口中定义。而其他的关于Bean的原生操作方法,如getType、containsBean、isSingleTon等接口均在BeanFactory.java中定义。

  • This interface is implemented by objects that hold a number of bean definitions,each uniquely identified by a String name.

这句话解释了BeanFactory接口由哪些对象使用。由包含多个bean定义的对象使用。每一个bean对象拥有一个String类型的name来作为唯一标识,不可重复。

层层依赖的接口关系

下图是实现了BeanFactory依赖关系

image.png
由上图可知,在Spring体系中关于Bean的定义操作都在上图中有体现。下面搞清楚各个接口的作用

ConfigurableBeanFactory

Configuration interface to be implemented by most bean factories. 
Provides facilities to configure a bean factory, 
in addition to the bean factory client methods in the {@link org.springframework.beans.factory.BeanFactory} interface

AutowireCapableBeanFactory

官方注释

Extension of the {@link org.springframework.beans.factory.BeanFactory} interface to be implemented by bean factories that are capable of autowiring, provided that they want to expose this functionality for existing bean instances

方法实现

image.png


该接口是支持自动装配的BeanFactory.是对BeanFactory接口的扩展。被支持自动装配的 bean factories 所实现。通俗点讲:通过该接口创建的Bean将会被公开暴露使用。

  • 主要定义的方法及其作用
createBean
Fully create a new bean instance of the given class
<p>Performs full initialization of the bean, including all applicable {@link BeanPostProcessor BeanPostProcessors}.
Note: This is intended for creating a fresh instance, populating annotated fields and methods as well as applying all standard bean initialization callbacks.
It does <i>not</> imply traditional by-name or by-type autowiring of properties;
use {@link #createBean(Class, int, boolean)} for those purposes.

通过给定的class,完全地创建一个新的Bean实例
执行bean的完全初始化,包含了所有可用的 BeanPostProcessors
注意:这是为了创建一个新的bean实例 
autowireBean

依赖注入的体现

	/**
	 * Populate the given bean instance through applying after-instantiation callbacks
	 * and bean property post-processing (e.g. for annotation-driven injection).
	 * <p>Note: This is essentially intended for (re-)populating annotated fields and
	 * methods, either for new instances or for deserialized instances. It does
	 * <i>not</i> imply traditional by-name or by-type autowiring of properties;
	 * use {@link #autowireBeanProperties} for those purposes.
	 * @param existingBean the existing bean instance
	 * @throws BeansException if wiring failed
	 */

应用于Bean实例化之后回调和Bean属性后置处理器来给指定的Bean进行注入
configureBean
	/**
	 * Configure the given raw bean: autowiring bean properties, applying
	 * bean property values, applying factory callbacks such as {@code setBeanName}
	 * and {@code setBeanFactory}, and also applying all bean post processors
	 * (including ones which might wrap the given raw bean).
	 * <p>This is effectively a superset of what {@link #initializeBean} provides,
	 * fully applying the configuration specified by the corresponding bean definition.
	 * <b>Note: This method requires a bean definition for the given name!</b>
	 * @param existingBean the existing bean instance
	 * @param beanName the name of the bean, to be passed to it if necessary
	 * (a bean definition of that name has to be available)
	 * @return the bean instance to use, either the original or a wrapped one
	 * @throws org.springframework.beans.factory.NoSuchBeanDefinitionException
	 * if there is no bean definition with the given name
	 * @throws BeansException if the initialization failed
	 * @see #initializeBean
	 */

对原始Bean进行相关配置,自动装配bean的属性

该方法具体实现的功能

	@Override
	public Object configureBean(Object existingBean, String beanName) throws BeansException {
		// 首先把bean标记为已创建
		markBeanAsCreated(beanName);
		// 拿到 beanDefinition
		BeanDefinition mbd = getMergedBeanDefinition(beanName);
		RootBeanDefinition bd = null;
		if (mbd instanceof RootBeanDefinition) {
			RootBeanDefinition rbd = (RootBeanDefinition) mbd;
			bd = (rbd.isPrototype() ? rbd : rbd.cloneBeanDefinition());
		}
		if (bd == null) {
			bd = new RootBeanDefinition(mbd);
		}
		if (!bd.isPrototype()) {
			bd.setScope(BeanDefinition.SCOPE_PROTOTYPE);
			bd.allowCaching = ClassUtils.isCacheSafe(ClassUtils.getUserClass(existingBean), getBeanClassLoader());
		}
		// bean 的包装器  设置了属性  defaultEditorsActive=true
		BeanWrapper bw = new BeanWrapperImpl(existingBean);
		// 初始化wrapper,读取bean标签的配置信息
		initBeanWrapper(bw);
		// 注入bean属性
		populateBean(beanName, bd, bw);
		// For the nullability warning, see the elaboration in AbstractBeanFactory.doGetBean;
		// in short: This is never going to be null unless user-declared code enforces null.
		// 真正去初始化bean
		return initializeBean(beanName, existingBean, bd);
	}

    //  双重检查锁,单例模式的运用.也体现了_spring创建bean是以多线程的方式创建的
	protected void markBeanAsCreated(String beanName) {
		if (!this.alreadyCreated.contains(beanName)) {
			synchronized (this.mergedBeanDefinitions) {
				if (!this.alreadyCreated.contains(beanName)) {
					// Let the bean definition get re-merged now that we're actually creating
					// the bean... just in case some of its metadata changed in the meantime.
                    //  从待创建状态进入标记创建状态
					clearMergedBeanDefinition(beanName);
					this.alreadyCreated.add(beanName);
				}
			}
		}
	}
autowire

Instantiate a new bean instance of the given class with the specified autowire strategy
实例化一个新的Bean实例通过给定的类使用指定的自动装配策略

autowireBeanProperties

Autowire the bean properties of the given bean instance by name or type
通过name or type来给指定的类自动装配bean属性

applyBeanPropertyValues

Apply the property values of the bean definition with the given name to the given bean instance
应用属性值到bean definition

initializeBean
Initialize the given raw bean, applying factory callbacks such as {@code setBeanName} and {@code setBeanFactory}, 
also applying all bean post processors (including ones which might wrap the given raw bean)

初始化一个原始的bean.  
应用于以下四种地方
	setBeanName
  setBeanFactory
  bean post processors
  wrap the given ram bean
applyBeanPostProcessorsBeforeInitialization

Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean instance, invoking their {@code postProcessBeforeInitialization} methods.
The returned bean instance may be a wrapper around the original.

applyBeanPostProcessorsAfterInitialization
Apply {@link BeanPostProcessor BeanPostProcessors} to the given existing bean instance, invoking their {@code postProcessAfterInitialization} methods.
The returned bean instance may be a wrapper around the original

HierarchicaBeanFactory

提供获取Bean Factory的 parent Bean Factory接口

Sub-interface implemented by bean factories that can be part of a hierarchy

如果一个bean是层次结构中的一部分,可以实现该接口

ListableBeanFactory

Extension of the {@link BeanFactory} interface to be implemented by bean factories that can enumerate all their bean instances, 
rather than attempting bean lookup by name one by one as requested by clients. 
BeanFactory implementations that preload all their bean definitions (such as XML-based factories) may implement this interface.

image.png

主要定义了BeanDefinition相关操作

ConfigurableListableBeanFactory

* Configuration interface to be implemented by most listable bean factories.
* In addition to {@link ConfigurableBeanFactory}, it provides facilities to
* analyze and modify bean definitions, and to pre-instantiate singletons.

ApplicationContext

Central interface to provide configuration for an application.
This is read-only while the application is running, but may be
reloaded if the implementation supports this.

ConfigurableApplicationContext

SPI interface to be implemented by most if not all application contexts.
Provides facilities to configure an application context in addition
to the application context client methods in the
{@link org.springframework.context.ApplicationContext} interface.

WebApplicationContext

Interface to provide configuration for a web application. This is read-only while
the application is running, but may be reloaded if the implementation supports this.

ConfigurableWebApplicationContext

Interface to be implemented by configurable web application contexts.
Supported by {@link ContextLoader} and
{@link org.springframework.web.servlet.FrameworkServlet}.
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。