spring 源码分析(二)Core
sschrodinger
2019/03/14
参考
Spring 中 Bean 的生命周期是怎样的?-
大闲人柴毛毛
Spring Bean Life Cycle Explained - by - Lokesh Gupta
基于 spring centext 5.1.3.RELEASE
简介
在 spring 中,使用 Bean 代指 spring 所管理的类,如上一节的 ServiceImpl,同时,spring 也规定了 Bean 的生命周期,不同于普通类从载入到被垃圾回收器回收的生命周期,spring 实现了更加详尽的生命周期。spring bean 的生命周期如下:
- 实例化 bean 对象,即 new XX();
- 填充对象属性
- 检查Aware相关接口并设置相关依赖
- BeanPostProcessor 前置处理
- 检查是否是 InitializingBean 决定是否调用 afterPropertiesSet 方法,检查是否有自定义的 init-method,有的话调用
- BeanPosetProcessor 后置处理
- 注册必要的 Destruction 相关回调接口
- 使用
- 是否实现 DisposableBean 相关接口,是的话执行 destroy() 函数。
- 是否有自定义 destroy 方法,是的话执行。
详细解释参见大闲人柴毛毛知乎
组件简介
BeanFactory
BeanFactory 是 spring 最基本的一个库,BeanFactory 实现了 Bean 对象的管理,包括如何利用 Bean 的名字获得 Bean 对象等。BeanFactory 的接口如下:
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
//根据 bean name 获得bean 对象
Object getBean(String name) throws BeansException;
//根据 bean name 获得 bean 对象并转化成正确类型
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
//利用 bean name 获得 bean 对象,并用 args 覆盖一些配置
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
boolean containsBean(String name);
//bean 是否为单例模式
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
//是否为 原型模式
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
}
依据 BeanFactory 所派生的接口非常复杂,大概有 20 个左右的类。典型的接口如下:
//顾名思义,层级 BeanFactory,可以获得上一级 BeanFatory,并且可以判断某名字的 Bean 是否在该 BeanFacory 中。
public interface HierarchicalBeanFactory extends BeanFactory {
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
}
//能够自动注解的类
public interface AutowireCapableBeanFactory extends BeanFactory {
int AUTOWIRE_NO = 0;
int AUTOWIRE_BY_NAME = 1;
int AUTOWIRE_BY_TYPE = 2;
int AUTOWIRE_CONSTRUCTOR = 3;
@Deprecated
int AUTOWIRE_AUTODETECT = 4;
String ORIGINAL_INSTANCE_SUFFIX = ".ORIGINAL";
<T> T createBean(Class<T> beanClass) throws BeansException;
void autowireBean(Object existingBean) throws BeansException;
Object configureBean(Object existingBean, String beanName) throws BeansException;
//-------------------------------------------------------------------------
// Specialized methods for fine-grained control over the bean lifecycle
//-------------------------------------------------------------------------
Object createBean(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
Object autowire(Class<?> beanClass, int autowireMode, boolean dependencyCheck) throws BeansException;
void autowireBeanProperties(Object existingBean, int autowireMode, boolean dependencyCheck)
throws BeansException;
void applyBeanPropertyValues(Object existingBean, String beanName) throws BeansException;
Object initializeBean(Object existingBean, String beanName) throws BeansException;
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException;
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException;
void destroyBean(Object existingBean);
//-------------------------------------------------------------------------
// Delegate methods for resolving injection points
//-------------------------------------------------------------------------
<T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException;
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName) throws BeansException;
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
@Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException;
}
//可以计数的 BeanFactory
public interface ListableBeanFactory extends BeanFactory {
boolean containsBeanDefinition(String beanName);
int getBeanDefinitionCount();
String[] getBeanDefinitionNames();
String[] getBeanNamesForType(ResolvableType type);
String[] getBeanNamesForType(@Nullable Class<?> type);
String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException;
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> annotationType) throws BeansException;
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
//最重要的一个接口,spring 中大部分的实例都是使用的该接口
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
@Nullable
String getId();
String getApplicationName();
String getDisplayName();
long getStartupDate();
@Nullable
ApplicationContext getParent();
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
ConfigurableApplicationContext 继承自 ApplicationContext,增加了一些配置的功能,如设置 context ID,最重要的是增加了 addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) 和 void refresh() throws BeansException, IllegalStateException 方法,用于实现 context 的刷新和初始化之前的一些操作。
BeanDefinition
用于保存每一个 bean 的定义。
BeanWrapper
用于封装需要注入的类,并提供 set 方式,以避免用反射的方式设置属性。
AbstractBeanDefinitionReader
AbstractBeanDefinitionReader 实现了 BeanDefinitionReader 接口和 EnvironmentCapable 接口,主要作用是读取配置文件并生成对应 Bean 的配置。
处理流程分析
以如下的代码分析处理流程,代码如下:
package ioc;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml");
Service service = (Service) context.getBean("serviceImpl");
service.doSomething();
}
}
package ioc;
public interface Service {
public void doSomething();
}
package ioc;
public class ServiceImpl implements Service {
public void doSomething() {
System.out.println(this.getClass().getName() + "#doSomething");
}
}
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean name="serviceImpl" class="ioc.ServiceImpl">
</bean>
</beans>
Bean 的生命周期分为10个步骤,按照步骤一步一步说明 BeanFactory 如何管理 Bean。
初始化
这里的初始化指的是 Bean 生命周期中 Bean 实例准备就绪之前的所有动作。
准备工作
Bean 的初始化始于 ApplicationContext context = new ClassPathXmlApplicationContext("spring_ioc.xml"),总结来说就是读取配置文件并生成实例。
ClaaPathXmlApplicationContext 是 AbstractXmlApplicationContext 的子类,作用就是从 classpath 中查找配置文件并对 Bean 进行初始化。
ClaaPathXmlApplicationContext 的初始化函数如下:
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[] {configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
实际上是调用继承的初始化函数,并对 Bean 刷新。
super(parent) 方法在 AbstractApplicationContext 中正真执行,代码如下:
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
this();
setParent(parent);
}
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
实际上作用只是获得一个 ResourcePatternResolver。
setConfigLocations(configLocations) 用于设定 confifLocation 的位置,并存储。
最重要的函数是 refresh 方法,通过 refresh 更新 BeanFactory,refresh 的方法实现在 AbstractApplicationContext 中,具体实现如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//step 1
// Prepare this context for refreshing.
prepareRefresh();
//step 2
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//step 3
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//step 4
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//step 5
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//step 6
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
//step 7
// Initialize message source for this context.
initMessageSource();
//step 8
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
//step 9
// Initialize other special beans in specific context subclasses.
onRefresh();
//step 10
// Check for listener beans and register them.
registerListeners();
//step 11
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
//step 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...
resetCommonCaches();
}
}
}
第一步
prepareRefresh()主要是做一些检查的工作,并将当前的 BeanFacory 的属性设置为激活。
第二步
obtainFreshBeanFactory 是真正的初始化函数,函数定义如下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
更新 BeanFactory 并将 BeanFactory 返回。其中,refreshBeanFactory() 交给了子类实现。具体的实现在 AbstractRefreshableApplicationContext 中。具体代码如下:
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
} catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
当存在 beanFactory 时,首先先注销原来的 BeanFactory,接下来创建一个新的内部 BeanFactory,设置序列号,并在 customizeBeanFactory(beanFactory) 中设置是否允许覆盖定义(默认允许),最重要的是 loadBeanDefinitions 函数,他负责了读取配置并对 Bean 进行加载。
loadBeanDefinitions 函数由其子类 AbstractXmlApplicationContext 实现。主要功能实解析 xml 文件并产生 Bean Definition。
解析 xml 文件
loadBeanDefinitions() 函数的实现如下:
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
可以看到主要是生成一个 XmlBeanDefinitionReader 实例对 xml 文件进行解析。以下的函数都是实现在其父类 AbstractBeanDefinitionReader 中的方法,提供通用的加载策略。最重要的是 loadBeanDefinitions(beanDefinitionReader) 函数。函数定义如下:
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
因为使用 configLocation 加载配置,所以 configResources 为空,Resource 接口定义了资源是否存在,资源是否准备好,资源是否是文件等信息,一般用于网络资源的加载。我们只关心以 Stringp[] 作为参数的 loadBeanDefinitions 函数。
定义如下:
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}
逻辑很简单,有多少个文件就执行多少次 loadDefinition 函数,并计数。真正的处理函数在 loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) 中。代码如下:
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
int count = loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
} else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (logger.isTraceEnabled()) {
logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
在 ClassPathXmlApplicationContext 的实现中,他既继承了 BeanFactory,也同时继承了 ResourceLoader 和 ResourcePatternResolver 即可以实现资源的加载和将 url 封装成 Resource 的功能。
url 经过解析之后,实际上还是调用的 loadDefinifions(Resource[]),这时,Resource 中包含了 path 和类加载器。我们再看 loadDefinifions(Resource[]),定义如下:
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
count += loadBeanDefinitions(resource);
}
return count;
}
loadBeanDefinitions(Resource) 由其子类重写,用来加载真正的资源。XmlBeanDefinitionReader 实现如下:
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResource 封装了 encode 方法和 encode 的编码类型
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
//resourcesCurrentlyBeingLoaded 是一个 ThreadLocal 变量,用于安全的线程中存储数据.
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (currentResources == null) {
currentResources = new HashSet<>(4);
this.resourcesCurrentlyBeingLoaded.set(currentResources);
}
//将 encodedResource 添加到 ThreadLocal 中。
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//解析数据
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} finally {
inputStream.close();
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch...
}
doLoadBeanDefinitions 主要有两个步骤,第一个步骤是获得 xml 的 Document 文档,第二个步骤是将文档中的 Bean 定义注册到 context 中。
第一个步骤的代码如下:
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
//生成 Document,利用 EntityResolver 解析 SAX 文件(DTD等),生成Document
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
第二个步骤的代码如下:
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
Registry 是存储 Bean 的结构,在这里,默认使用 DefaultListableBeanFactory 实现。解析 Document 文件并根据解析结果将 BeanDefinition 存储在 Regist 中。
第三步
prepareBeanFactory 主要是对 beanFactory 做一些初始化,比如说设置 classLoader,忽略的接口,并提前注册一些 Bean,如使用 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory) 函数注册他自身,或者注册单例模式(使用 beanFactory.registerSingleton()函数)。代码如下:
/**
* 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());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
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.
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.
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());
}
}
第四步
postProcessBeanFactory(beanFactory) 允许子类对 beanFactory 做一些自定义的操作,这里没有实现,是一个空方法。
第五步
invokeBeanFactoryPostProcessors 实例化所有注册的的 BeanFactoryPostProcessor Bean。
第六步
registerBeanPostProcessors(beanFactory) 注册预处理器。
第七步
initMessageSource(),初始化数据源。
第八步
initApplicationEventMulticaster(),初始化多播器。
第九步
onRefresh(),更新。子类未实现。
第十步
registerListeners() 第九步,注册监听器
第十一步
finishBeanFactoryInitialization() 初始化所有剩下的Beans,集体实现如下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
//此时禁止配置,以防止出现不可预料的问题
beanFactory.freezeConfiguration();
//初始化剩下的单例 Bean
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
重点函数在 preInstantiateSingletons 上。这个函数负责真正加载单例 Bean。代码如下:
@Override
public void preInstantiateSingletons() throws BeansException {
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
} else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
首先获得所有 Bean 的名字,通过名字获得 BeanDefinition,如果不是 FactoryBean 的话,执行 getBean(beanName)。
getBean() 由 doGetBean() 具体实现,实现是在 AbstractBeanFactory 中,具体实现如下:
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// phase 1
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// phase 2
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
} else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// phase 3
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
} catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// phase 4
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
} else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
} else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
} catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
} catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
} catch (TypeMismatchException ex) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
代码非常的长,将其分段。
第一阶段,主要是在人工注入的 Register 中有没有 Bean,如果有,返回。
第二阶段,检查父节点中有没有 Bean,有,返回。
第三阶段,主要是检查 有没有循环依赖,循环依赖的报错就是在这产生的。并且初始化所有的依赖 Bean。
第四阶段,调用 createBean(beanName, mbd, args) 新建一个单例 bean。在这一阶段,做了生命周期中大量的工作,包括初始化 Bean、填充属性、如果继承自 BeanNameAware,设置 Bean name、如果继承自 BeanFactoryAware,设置 BeanFactory、调用BeanPostProcessor的 postProcessBeforeInitialization 做一些前期处理、如果继承了 InitializingBean 接口,则调用 afterPropertiesSet 方法、如果继承了 BeanPostProcess 接口,则调用 postProcessAfterInitialization 方法。可以说,这一步,实现了 Bean 大部分的生命周期函数。
第十二步
finishRefresh(),主要是做一些收尾工作。
至此,初始化 Bean 的工作九到此结束。
使用过程
使用过程和初始化复用了大量的代码,主要是 getBean() 函数的代码,唯一的区别是在初始化时,要新建实例,而使用时直接从缓存中读取数据并返回。









网友评论