启动流程
核心步骤
1.应用程序的入口
启动项目。
2.创建BeanDefinition,然后写到容器类的BeanDefinition集合里去(具体数据结构是一个map)
通过注解或者读xml文件的方式,得到BeanDefinition。
3.创建bean实例对象
非业务bean(即spring框架里自带的各种bean),一般都提前创建实例,即在启动的时候就创建了。
方法调用栈
resolveBean:407, DefaultListableBeanFactory (org.springframework.beans.factory.support)
getBean:341, DefaultListableBeanFactory (org.springframework.beans.factory.support)
getBean:335, DefaultListableBeanFactory (org.springframework.beans.factory.support)
getConfigurableWebBindingInitializer:538, WebMvcAutoConfiguration$EnableWebMvcConfiguration (org.springframework.boot.autoconfigure.web.servlet)
requestMappingHandlerAdapter:564, WebMvcConfigurationSupport (org.springframework.web.servlet.config.annotation)
requestMappingHandlerAdapter:484, WebMvcAutoConfiguration$EnableWebMvcConfiguration (org.springframework.boot.autoconfigure.web.servlet)
CGLIB$requestMappingHandlerAdapter$4:-1, WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$6dc0a0b8 (org.springframework.boot.autoconfigure.web.servlet)
invoke:-1, WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$6dc0a0b8$$FastClassBySpringCGLIB$$51fe5d3e (org.springframework.boot.autoconfigure.web.servlet)
invokeSuper:244, MethodProxy (org.springframework.cglib.proxy)
intercept:363, ConfigurationClassEnhancer$BeanMethodInterceptor (org.springframework.context.annotation)
requestMappingHandlerAdapter:-1, WebMvcAutoConfiguration$EnableWebMvcConfiguration$$EnhancerBySpringCGLIB$$6dc0a0b8 (org.springframework.boot.autoconfigure.web.servlet)
invoke0:-1, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:62, NativeMethodAccessorImpl (jdk.internal.reflect)
invoke:43, DelegatingMethodAccessorImpl (jdk.internal.reflect)
invoke:566, Method (java.lang.reflect)
instantiate:154, SimpleInstantiationStrategy (org.springframework.beans.factory.support)
instantiate:622, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:607, ConstructorResolver (org.springframework.beans.factory.support)
instantiateUsingFactoryMethod:1321, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBeanInstance:1160, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:555, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:515, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:320, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 596910004 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$160)
getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:318, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:199, AbstractBeanFactory (org.springframework.beans.factory.support) //创建非业务bean,即spring框架里自带的各种bean
preInstantiateSingletons:849, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:877, AbstractApplicationContext (org.springframework.context.support)
refresh:549, AbstractApplicationContext (org.springframework.context.support)
refresh:142, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:775, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:316, SpringApplication (org.springframework.boot)
run:1260, SpringApplication (org.springframework.boot)
run:1248, SpringApplication (org.springframework.boot)
main:58, SampleTomcatApplication (sample.tomcat) //应用程序的入口
bean实例对象存储在哪里?
源码
/**
* Generic registry for shared bean instances, implementing the
* {@link org.springframework.beans.factory.config.SingletonBeanRegistry}.
* Allows for registering singleton instances that should be shared
* for all callers of the registry, to be obtained via bean name.
*
* <p>Also supports registration of
* {@link org.springframework.beans.factory.DisposableBean} instances,
* (which might or might not correspond to registered singletons),
* to be destroyed on shutdown of the registry. Dependencies between
* beans can be registered to enforce an appropriate shutdown order.
*
* <p>This class mainly serves as base class for
* {@link org.springframework.beans.factory.BeanFactory} implementations,
* factoring out the common management of singleton bean instances. Note that
* the {@link org.springframework.beans.factory.config.ConfigurableBeanFactory}
* interface extends the {@link SingletonBeanRegistry} interface.
*
* <p>Note that this class assumes neither a bean definition concept
* nor a specific creation process for bean instances, in contrast to
* {@link AbstractBeanFactory} and {@link DefaultListableBeanFactory}
* (which inherit from it). Can alternatively also be used as a nested
* helper to delegate to.
*
* @author Juergen Hoeller
* @since 2.0
* @see #registerSingleton
* @see #registerDisposableBean
* @see org.springframework.beans.factory.DisposableBean
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory
*/
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/**
* Add the given singleton object to the singleton cache of this factory.
* <p>To be called for eager registration of singletons.
* @param beanName the name of the bean
* @param singletonObject the singleton object
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject); //添加bean实例到map
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
依赖bean存储在哪里?
不管是bean,还是bean的依赖bean/注入bean,都分2个部分
1.bean定义
2.bean实例对象
依赖数据也是bean,所以也是一样。
而且最为重要的一点是,因为bean定义和bean实例对象是2个不同的东西,而且存储的地方也不一样。
所以容器的几个核心问题就是下面的几点。
1.bean定义
xml bean定义映射为BeanDefinition类的对象,BeanDefinition对象专门有一个map存储,这个map就是容器核心实现类DefaultListableBeanFactory的属性beanDefinitionMap。
2.bean实例对象
第一次用的时候,容器会创建bean实例对象,然后存储在DefaultSingletonBeanRegistry的属性singletonObjects。
3.依赖bean的定义
存储在这里,也是存储在map里。注意,这里存储的只是依赖bean的名字,而不是依赖bean实例对象。
DefaultSingletonBeanRegistry
/** Map between containing bean names: bean name to Set of bean names that the bean contains. */
private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16); //被依赖的bean
/** Map between dependent bean names: bean name to Set of dependent bean names. */
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64); //依赖的bean
/**
* Return the names of all beans which depend on the specified bean, if any.
* @param beanName the name of the bean
* @return the array of dependent bean names, or an empty array if none
*/
public String[] getDependentBeans(String beanName) { //获取依赖bean
Set<String> dependentBeans = this.dependentBeanMap.get(beanName);
if (dependentBeans == null) {
return new String[0];
}
synchronized (this.dependentBeanMap) {
return StringUtils.toStringArray(dependentBeans);
}
}
应用程序可以通过以下方法打印出来。
@GetMapping("/getBeanDefinitionNames")
public void getBeanDefinitionNames() {
log.info("start");
log.info("bean数量:" + applicationContext.getBeanDefinitionCount());
log.info("bean名字:" + JSONObject.toJSONString(applicationContext.getBeanDefinitionNames()));
//
DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory(); //获取容器
log.info("sampleController:" + defaultListableBeanFactory.getBean("sampleController").getClass()); //获取bean
log.info("被依赖的bean:" + JSONObject.toJSONString(defaultListableBeanFactory.getDependentBeans("sampleController")));
log.info("依赖的bean:" + JSONObject.toJSONString(defaultListableBeanFactory.getDependenciesForBean("sampleController")));
}
(这张类继承图,标注了以上数据被存储在了哪个类)
4.依赖bean实例对象
何时创建?
存储在哪里?
也是和bean一样,存储在容器实现类的map里去,因为依赖bean也是bean,和宿主bean完全一样,没有任何区别。唯一的区别,就是依赖关系的区别。
从这张图可以看出来,核心流程是
1.创建bean实例
2.创建注入bean实例
1)和创建bean实例的流程完全一样,因为本来就是一个递归创建,即创建bean,然后再创建bean的依赖bean,一直这样递归下去,直到最后一个依赖bean没有自己的依赖bean为止。
2)并且,还要添加依赖关系,即把依赖bean添加到宿主bean的依赖bean-map里去。依赖bean-map,只是存储了宿主bean名字和依赖bean名字集合。不是存储依赖bean实例对象,因为依赖bean实例对象的存储是和宿主bean的存储是在同一个地方,即都是在存储容器实现类的bean-map里。
(这张类继承图,标注了以上数据被存储在了哪个类)
以上存储内容和BeanDefinition存储内容的区别和对比?
BeanDefinition
是什么?是xml bean的映射。
包含了什么内容?比如,包含了bean名字。
BeanDefinition实现类的类继承图
bean的属性存储在这里
每个属性的本质其实就是属性名字和属性的值,属性名字就是变量名字,属性的值就是类的名字,而不是实际的实例对象。
这里的属性存储的是是所有属性?还是只是依赖bean?
只是依赖bean属性,其他属性不存储,因为创建bean的依赖bean的实例对象的时候,是根据这个属性来创建的。由此可见,BeanDefinition是创建bean实例和创建依赖bean实例的一个基础依据,即定义了bean和它的依赖bean,虽然这里不是真正创建bean实例的地方,但是真正创建bean实例和依赖bean的实例对象的时候,都是根据BeanDefinition这里的定义来创建的。
容器实现类DefaultListableBeanFactory
bean实例对象
bean的依赖bean
和bean完全一样
源码分析
创建bean实例对象
创建依赖bean的实例对象
/**
* Populate the bean instance in the given BeanWrapper with the property values
* from the bean definition.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param bw the BeanWrapper with bean instance
*/
@SuppressWarnings("deprecation") // for postProcessPropertyValues
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
boolean continueWithPropertyPopulation = true;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
if (!continueWithPropertyPopulation) {
return;
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //获取bean属性
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
if (pvs != null) { //如果bean属性不为空,就创建依赖bean的实例对象
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
/**
* Apply the given property values, resolving any runtime references
* to other beans in this bean factory. Must use deep copy, so we
* don't permanently modify this property.
* @param beanName the bean name passed for better exception information
* @param mbd the merged bean definition
* @param bw the BeanWrapper wrapping the target object
* @param pvs the new property values
*/
protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
if (pvs.isEmpty()) {
return;
}
if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
}
MutablePropertyValues mpvs = null;
List<PropertyValue> original;
if (pvs instanceof MutablePropertyValues) {
mpvs = (MutablePropertyValues) pvs;
if (mpvs.isConverted()) {
// Shortcut: use the pre-converted values as-is.
try {
bw.setPropertyValues(mpvs);
return;
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
original = mpvs.getPropertyValueList();
}
else {
original = Arrays.asList(pvs.getPropertyValues());
}
TypeConverter converter = getCustomTypeConverter();
if (converter == null) {
converter = bw;
}
BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);
// Create a deep copy, resolving any references for values.
List<PropertyValue> deepCopy = new ArrayList<>(original.size());
boolean resolveNecessary = false;
for (PropertyValue pv : original) {
if (pv.isConverted()) {
deepCopy.add(pv);
}
else {
String propertyName = pv.getName();
Object originalValue = pv.getValue();
Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue); //创建依赖bean的实例对象
Object convertedValue = resolvedValue;
boolean convertible = bw.isWritableProperty(propertyName) &&
!PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
if (convertible) {
convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
}
// Possibly store converted value in merged bean definition,
// in order to avoid re-conversion for every created bean instance.
if (resolvedValue == originalValue) {
if (convertible) {
pv.setConvertedValue(convertedValue);
}
deepCopy.add(pv);
}
else if (convertible && originalValue instanceof TypedStringValue &&
!((TypedStringValue) originalValue).isDynamic() &&
!(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
pv.setConvertedValue(convertedValue);
deepCopy.add(pv);
}
else {
resolveNecessary = true;
deepCopy.add(new PropertyValue(pv, convertedValue)); //
}
}
}
if (mpvs != null && !resolveNecessary) {
mpvs.setConverted();
}
// Set our (possibly massaged) deep copy.
try {
bw.setPropertyValues(new MutablePropertyValues(deepCopy)); //
}
catch (BeansException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Error setting property values", ex);
}
}
创建依赖bean的实例对象,后面的流程和创建bean完全一样。
/**
* Resolve a reference to another bean in the factory.
*/
@Nullable
private Object resolveReference(Object argName, RuntimeBeanReference ref) {
try {
Object bean;
String refName = ref.getBeanName();
refName = String.valueOf(doEvaluate(refName));
if (ref.isToParent()) {
if (this.beanFactory.getParentBeanFactory() == null) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Can't resolve reference to bean '" + refName +
"' in parent factory: no parent factory available");
}
bean = this.beanFactory.getParentBeanFactory().getBean(refName);
}
else {
bean = this.beanFactory.getBean(refName); //创建依赖bean的实例对象
this.beanFactory.registerDependentBean(refName, this.beanName); //添加依赖bean到map里去
}
if (bean instanceof NullBean) {
bean = null;
}
return bean;
}
catch (BeansException ex) {
throw new BeanCreationException(
this.beanDefinition.getResourceDescription(), this.beanName,
"Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
}
}
方法调用栈
getBean:199, AbstractBeanFactory (org.springframework.beans.factory.support) //创建依赖bean的实例对象
resolveReference:367, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
resolveValueIfNecessary:110, BeanDefinitionValueResolver (org.springframework.beans.factory.support)
applyPropertyValues:1681, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
populateBean:1433, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support) //开始处理依赖bean
doCreateBean:592, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:515, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:320, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 616881582 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$160)
getSingleton:222, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:318, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:204, AbstractBeanFactory (org.springframework.beans.factory.support) //创建bean的实例对象
invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:705, AbstractApplicationContext (org.springframework.context.support)
refresh:531, AbstractApplicationContext (org.springframework.context.support)
refresh:142, ServletWebServerApplicationContext (org.springframework.boot.web.servlet.context)
refresh:775, SpringApplication (org.springframework.boot)
refreshContext:397, SpringApplication (org.springframework.boot)
run:316, SpringApplication (org.springframework.boot)
run:1260, SpringApplication (org.springframework.boot)
run:1248, SpringApplication (org.springframework.boot)
main:58, SampleTomcatApplication (sample.tomcat) //入口:启动应用程序