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()
函数的代码,唯一的区别是在初始化时,要新建实例,而使用时直接从缓存中读取数据并返回。
网友评论