Spring是如何启动的
在SpringBoot出现之前,我们使用Spring需要以配置文件的方式进行启动.如果使用XML文件配置.则通过XmlWebApplicationContext.java
进行启动.常应用在Web项目的开发中.
以此为例,通过阅读源码发现和XmlWebApplicationContext.java
“平级”的类如下所示
由此我们可以知道ApplicationContext
遵循ApplicationContext.java
的定义.如下所示其父依赖结构
此时我们可以看到最顶层的接口BeanFactory.java
揭开BeanFactory的面纱
BeanFactory本质是一个赤裸裸的接口
忽略掉繁杂的定义,BeanFactory.java 本质上就是一个接口——其中定义了一些方法。如下图示——并没有太多复杂的东西。
从官方注释提炼重要信息
- 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依赖关系
由上图可知,在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
方法实现
该接口是支持自动装配的BeanFactory.是对BeanFactory接口的扩展。被支持自动装配的 bean factories 所实现。通俗点讲:通过该接口创建的Bean将会被公开暴露使用。
- 主要定义的方法及其作用
createBean
Fully create a new bean instance of the given class
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 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).
* Note: This is essentially intended for (re-)populating annotated fields and
* methods, either for new instances or for deserialized instances. It does
* not 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).
* This is effectively a superset of what {@link #initializeBean} provides,
* fully applying the configuration specified by the corresponding bean definition.
* Note: This method requires a bean definition for the given name!
* @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.
主要定义了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}.
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.e1idc.net