0. 面试前顺手回顾一下
源码走读通过xml配置的方式注入bean
一位大佬关于Spring的系列博客
关于spring bean生命周期中解决循环依赖的讨论
1. 几个需要关注的类
1.1 盗来的图
ApplicationContext.java:
BeanFactory.java:
1.2 简述
DefaultListableBeanFactory
BeanFactory的实现类,扩展了维护多个bean的能力(BeanFactory的api是管理单个bean的)
集成了xml、注解方式的bean注入能力
ApplicationContext
内部维护了DefaultListableBeanFactory
refresh()
初始化BeanFactory
调用beanFactoryPostProcessor执行beanFactory生命周期钩子的方法
注册bean的生命周期钩子接口beanPostProcessor
(初始化国际化组件)
初始化事件广播组件
注册监听器
初始化除懒加载以外的单例Bean
广播ApplicationContext初始化完成的事件
AnnotationConfigApplicationContext
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry
AnnotatedBeanDefinitionReader(AnnotationConfigRegistry this)
通过注解注册BeanDefinitionHolder
this.aliasMap.put(alias, name);
beanName默认取ClassUtils.getShortName(beanClassName);
ClassPathBeanDefinitionScanner(AnnotationConfigRegistry this)
通过类路径注册BeanDefinitionHolder,同理
Bean
对转交给ioc容器中的java.lang.Object的一个抽象,并没有对应的实体
BeanDefinition
从xml、注解中读取到的配置信息
见源码
BeanDefinitionHolder
将beanDefinition解析后(beanName、别名)得到的bean的元数据
内部引用了BeanDefinition
BeanPostProcessor
BeanFactoryPostProcessor
2. 摘取几段源码
package org.springframework.beans.factory.support;
@SuppressWarnings("serial")
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
/** Resolver to use for checking if a bean definition is an autowire candidate. */
private AutowireCandidateResolver autowireCandidateResolver = SimpleAutowireCandidateResolver.INSTANCE;
/** Map from dependency type to corresponding autowired value. */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
/** Map of bean definition objects, keyed by bean name. */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/** Map from bean name to merged BeanDefinitionHolder. */
private final Map<String, BeanDefinitionHolder> mergedBeanDefinitionHolders = new ConcurrentHashMap<>(256);
/** Map of singleton and non-singleton bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
/** Map of singleton-only bean names, keyed by dependency type. */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
}
------------------
public interface BeanDefinitionRegistry extends AliasRegistry {
}
------------------
package org.springframework.beans.factory.config;
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;
int ROLE_APPLICATION = 0;
int ROLE_SUPPORT = 1;
int ROLE_INFRASTRUCTURE = 2;
void setParentName(@Nullable String parentName);
String getParentName();
void setBeanClassName(@Nullable String beanClassName);
String getBeanClassName();
void setLazyInit(boolean lazyInit);
boolean isLazyInit();
void setAutowireCandidate(boolean autowireCandidate);
boolean isAutowireCandidate();
void setPrimary(boolean primary);
boolean isPrimary();
void setFactoryBeanName(@Nullable String factoryBeanName);
String getFactoryBeanName();
void setFactoryMethodName(@Nullable String factoryMethodName);
String getFactoryMethodName();
ConstructorArgumentValues getConstructorArgumentValues();
default boolean hasConstructorArgumentValues() {
return !getConstructorArgumentValues().isEmpty();
}
MutablePropertyValues getPropertyValues();
default boolean hasPropertyValues() {
return !getPropertyValues().isEmpty();
}
void setInitMethodName(@Nullable String initMethodName);
String getInitMethodName();
void setDestroyMethodName(@Nullable String destroyMethodName);
String getDestroyMethodName();
void setDescription(@Nullable String description);
String getDescription();
ResolvableType getResolvableType();
boolean isSingleton();
boolean isPrototype();
boolean isAbstract();
}
---------------------------------------
public class BeanDefinitionHolder implements BeanMetadataElement {
private final BeanDefinition beanDefinition;
private final String beanName;
private final String[] aliases;
}
-----------------------------------------
public class SpringApplication {
/**
* The class name of application context that will be used by default for non-web
* environments.
*/
public static final String DEFAULT_CONTEXT_CLASS = "org.springframework.context."
+ "annotation.AnnotationConfigApplicationContext";
/**
* The class name of application context that will be used by default for web
* environments.
*/
public static final String DEFAULT_SERVLET_WEB_CONTEXT_CLASS = "org.springframework.boot."
+ "web.servlet.context.AnnotationConfigServletWebServerApplicationContext";
/**
* The class name of application context that will be used by default for reactive web
* environments.
*/
public static final String DEFAULT_REACTIVE_WEB_CONTEXT_CLASS = "org.springframework."
+ "boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext";
/**
* Default banner location.
*/
public static final String BANNER_LOCATION_PROPERTY_VALUE = SpringApplicationBannerPrinter.DEFAULT_BANNER_LOCATION;
/**
* Banner location property key.
*/
public static final String BANNER_LOCATION_PROPERTY = SpringApplicationBannerPrinter.BANNER_LOCATION_PROPERTY;
private static final String SYSTEM_PROPERTY_JAVA_AWT_HEADLESS = "java.awt.headless";
private static final Log logger = LogFactory.getLog(SpringApplication.class);
private Set<Class<?>> primarySources;
private Set<String> sources = new LinkedHashSet<>();
private Class<?> mainApplicationClass;
private Banner.Mode bannerMode = Banner.Mode.CONSOLE;
private boolean logStartupInfo = true;
private boolean addCommandLineProperties = true;
private boolean addConversionService = true;
private Banner banner;
private ResourceLoader resourceLoader;
private BeanNameGenerator beanNameGenerator;
private ConfigurableEnvironment environment;
private Class<? extends ConfigurableApplicationContext> applicationContextClass;
private WebApplicationType webApplicationType;
private boolean headless = true;
private boolean registerShutdownHook = true;
private List<ApplicationContextInitializer<?>> initializers;
private List<ApplicationListener<?>> listeners;
private Map<String, Object> defaultProperties;
private Set<String> additionalProfiles = new HashSet<>();
private boolean allowBeanDefinitionOverriding;
private boolean isCustomEnvironment = false;
private boolean lazyInitialization = false;
}
3. Bean生命周期
3.1 DefaultSingletonBeanRegistry
这个类并不关注bean defifinition或bean实例的创造过程,但是这个类维护了很多跟容器相关的Map
// 一级缓存 单例池 保存单例对象。 key: beanName value:bean
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
// 二级缓存,循环对象依赖列表 元对象池 在getSingleton()时会一级一级的判断 并且加入
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 三级缓存 工厂池 key: beanName value:beanFactory
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
3.2 单例的生命周期
图1:
图2: