先看看普通的实例化过程
Spring bean的实例化简图
可以看出spring的实例化是非常复杂的,接下来就去简单描述一下这个过程
Spring容器
- Spring IOC容器就是一个org.springframework.context.ApplicationContext的实例化对象
- 容器负责了实例化,配置以及装配一个bean
从代码层次来看:Spring容器就是一个实现了ApplicationContext接口的对象,
从功能上来看: Spring 容器是 Spring 框架的核心,是用来管理对象的。容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。
如何实例化一个Bean?
官网介绍
- 构造方法
- 通过静态工厂方法
- 通过实例工厂方法
这里记录一下源码分析过程吧*
首先这是AnnotationConfigApplicationContext的UML图
涉及到几个比较关键的类:GenericApplicationContext,AbstractApplicationContext,DefaultResourceLoader ,先放着
- 第一步当然是构造函数,AnnotationConfigApplication的初始化必然会先初始化父类
public AnnotationConfigApplicationContext(Class... annotatedClasses) {
this();
this.register(annotatedClasses);
this.refresh();
}
2.点击this();这个午餐构造方法进去,发现创建了 AnnotationBeanDefinitionReader
和 ClasspathBeanDefinitionScanner 这两个类各自去创建bean生成的环境。
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
3.进入 register方法 ,这里面主要是初始化Ban的各种注解
@SuppressWarnings("unchecked")
public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {//跳过处理
return;
}
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//获取@scope注解
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//取得bean名字
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//处理Lazy primary等注解,仅仅是设置属性。
if (qualifiers != null) {
for (Class<? extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//进入
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
static BeanDefinitionHolder applyScopedProxyMode(
ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
if (scopedProxyMode.equals(ScopedProxyMode.NO)) {//不需要代理直接返回
return definition;
}
boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);//默认是cglib的方式代理
return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
所以,register方法主要作用就是把bean上的注解扫描一遍。想是别名,懒加载,代理模式,scope等,将其注册到beanDefinitionRegistry(这个registry其实就是AnnotationConfigApplicationContext)中。
4. 很重要refresh();方法,这是AbstractApplicationContext种定义的方法。所有的AbstractApplicationContext容器的子类初始化都会经过这条路。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1.Prepare this context for refreshing.
prepareRefresh();
// 2.Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3.Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//4. Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// 5.Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// 6.Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 7.Initialize message source for this context.
initMessageSource();
// 8.Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 9.Initialize other special beans in specific context subclasses.
onRefresh();
// 10.Check for listener beans and register them.
registerListeners();
// 11.Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 12.Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
//13.
resetCommonCaches();
}
}
}
注意这个方法是加锁的,一共13个方法,分别来看下 每一步都干了什么。
// 1.Prepare this context for refreshing.
prepareRefresh();
顾名思义,是准备工作,这个和前面初始化的准备工作不同。这个是进行参数配置的。placeholder解析和校验工作,但是主要针对web项目的。暂时先不看。
// 2.Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
得到beanfactory
// 3.Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
下面展示一些 内联代码片
。
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
首先,设置了类加载器
beanFactory.setBeanClassLoader(getClassLoader());
添加对spel的支持,
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
添加一个默认的properties的处理工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
//设置需要忽略的类,这些类实现了如下的接口需要在bean创建的阶段在beanFactory的容器级别对自动装配进行忽略,而交由context容器进行callback注入。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
设置扩展点,对于这些扩展点接口的实现bean需要走特殊的callback流程,特殊装备规则。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
注册特殊的基础bean 如 environment systemEnvironment,systemProperties
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
//4. Allows post-processing of the bean factory in context subclasses. 给web项目使用,通常不会与自定义产生交集。
postProcessBeanFactory(beanFactory);
/* 5 … 扩展点开始,调用BeanFactoryPostProcessors接口的 postProcessBeanFactory 方法。这里有些细节,会有处理的优先级。
首先处理 BeanDefinitionRegistryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现,
然后处理 实现了BeanDefinitionRegistryPostProcessor接口不带order的类。
再然后处理 实现了 BeanFactoryPostProcessor 中带有PriorityOrdered ,Ordered 这些接口的实现。
最后处理 实现了 BeanFactoryPostProcessor 但没有order 接口的实现类。
这里也会进入 beanFactory获取Bean的关键方法 doGetBean();方法位于AbstractBeanFactory中。
getbean的实现比较简单,检查依赖 getDependsOn ,检查是否有循环依赖,有依赖的话先load依赖,AbstractAutowireCapableFactory 的 createBean();方法进行bean的创建。
最后是在SimpleInstantiationStrategy 调用 Beanutils.instantiateClass()通过调用无参构造函数newinstance();创建得到bean实例。如果是单例会被缓存一份。
//6.invokeBeanFactoryPostProcessors
主要是通过BeanDefinitionRegistry把实例对象的属性设置好放在map集合里面