Spring源码学习之旅 初识IOC
初识IOC
作为Spring最最重要与核心的功能,我们需要先去了解Spring IOC是个什么东东,经过五个大版本的发展, Spring容器已经由早期的纯XML配置转为0XML配置,但是从XML来开始了解Spring IOC会让人更加的理解它的发展历程,那就从XML开始吧
什么是IOC
- IOC,即 Inversion of Control,中文译名-控制反转,那么问题就来了,控制反转,反转的是什么控制?又是如何反转的?
- 其实Spring最早的时候只干了一件事,就是将实例化的过程帮助程序员实现了,原本一个个需要由程序员来new的对象,不再需要自己在A类里new出B类的实例了。即原来的对象实例化,是交给程序员控制的,但是在spring里,对象的实例化这件事交给了spring容器来做,将控制权交给了spring,这个就叫控制反转
- 那么如何把这件事交给spring做的呢,答案就是java的反射机制,当然中间的处理非常的繁琐,但是最核心的本质就是spring根据程序员提供的各类信息(xml配置、注解配置等)来控制类的实例化,避免程序员直接在A类中创建B类实例,造成代码的强耦合。
环境创建
Spring.xml
这个最基础的xml定义了一个Spring的bean对象,定义了它的属性为id,class对象是谁,通过标签可以看到里面的属性特别的多,一起总结一下
<?xml version="1.0" encoding="UTF-8"?>
<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 id="hello" class="com.xiaoyingge.spring.bean.BeanXml"/>
</beans>
<bean>标签的定义,这里声明了与它对应的类是BeanDefinition,基本上一套看下来,Spring在内部定义了一个类BeanDefinition,将其属性与Spring的<bean>配置文件进行一一对应,因此这也为后续通过注解直接进行bean定义提供了可能。
<xsd:element name="bean">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.beans.factory.config.BeanDefinition"><![CDATA[
Defines a single (usually named) bean.
A bean definition may contain nested tags for constructor arguments,
property values, lookup methods, and replaced methods. Mixing constructor
injection and setter injection on the same bean is explicitly supported.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="identifiedType">
<xsd:group ref="beanElements"/>
<xsd:attributeGroup ref="beanAttributes"/>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
重点要了解
- BeanDefinition ------- 向spring容器描述用户对于每一个Bean的准确定义
- BeanDefinitionRegister--------Spring中所有BeanDefinition的注册表,在ApplicationContext中体现为beanDefinitionMap
- BeanDefinitionNames--------所有bean名称的注册表
BeanDefinition
BeanDefinition可以看到是一个接口,Spring通常通过它的实现类 RootBeanDefinition和GenericBeanDefinition来对bean的定义进行包装,下面看下它的属性是如何与xml 的<bean>标签进行对应的
XML标签名 | BeanDefinition属性名 | 作用 |
---|---|---|
id | id | bean 的唯一标识 ,容器唯一 |
name | name | bean 的别名,可以任意由字母数据符号组合 |
class | beanClass | 对应的类的全限定名,子类可以不定义 |
parent | parentName | 对应的类的全限定名 |
abstract | abstract | 定义抽象bean,抽象bean不会进行实例化,通常用作父bean,提供通用属性继承给子bean |
lazy-init | lazyInit | 是否延迟加载,需要用到时才加载 |
autowired | autowireMode | 默认按类型type加载 no:不使用自动装配 byName:按bean名称装配 byType:按类型装配 constructor:按构造函数装配 autodetect:通过Bean的反省机制(introspection) 决定是按构造器装配还是按类型装配 |
depends-on | dependsOn | 依赖于谁,如果beanA中配置了dependsOn beanB, 那么在实例化beanA时会检查beanB有没有实例化, 如果B没有实例化,优先实例化beanB |
init-method | initMethodName | 无参初始化方法,在bean实例化之后调用 |
destory-method | destoryMethodName | 无参销毁方法,在beanFactory销毁时调用, applicationContext会触发上一个beanFactory的销毁运作 |
factory-method | factoryMethodName | 定义创建此类的工厂类,会导致class属性失效 |
autowire-candidate | autowireCandidate | |
MutablePropertyValues | propertyValues | 设置bean对象的各个属性 |
ConstructorArgumentValues | ConstructorArgumentValues | 构造函数的属性 |
MethodOverrides | setMethodOverrides | 用于封装look-up method和replaced-method |
从头开始
先看类的继承关系
重点关注下面几个类
- AbstractRefreshableConfigApplicationContext 持有配置文件路径属性,configLocations
- AbstractApplicationContext 定义了应用上下文的刷新模板方法
- ApplicationContext 应用上下文接口
- BeanFactory bean工厂接口
IOC流程(一) 加载配置
ClassPathXmlApplicationContext()
这里是我们测试方法的入口 ,就从这里开始,从构造方法里一路调用,最终会到这里
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
//父子容器使用,此处未用到,暂不分析
super(parent);
//设置配置文件的位置
setConfigLocations(configLocations);
if (refresh) {
//刷新容器方法
refresh();
}
}
AbstractRefreshableConfigApplicationContext.setConfigLocations()
先看setConfigLocations(configLocations);方法,它将配置文件的路径存放到父类的属性configLocations中
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
Assert.noNullElements(locations, "Config locations must not be null");
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
//将配置的文件路径存放到configLocations中
this.configLocations[i] = resolvePath(locations[i]).trim();**
}
}
else {
this.configLocations = null;
}
}
AbstractApplicationContext.refresh()
再看重点方法refresh(),它会调用AbstractApplicationContext里的refresh()方法,这个方法使用了模板方法模式,在AbstractApplicationContext里定义好了Spring容器的加载顺序,将部分方法的实现细节交由各个子类进行了实现
@Override
public void refresh() throws BeansException, IllegalStateException {
//不管三七二十一,先加锁
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//销毁原有工厂,可以返回自定义的bean工厂,默认返回DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//对bean工厂进行预处理,将一些spring需要使用的类先行实例化
//比如 ApplicationContextAwareProcessor
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// 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();
}
}
}
AbstractApplicationContext.obtainFreshBeanFactory()
本次我们主要看最简单的IOC过程是怎么实现的,因此其他的方法不在这里细看,主要看obtainFreshBeanFactory()方法
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新bean工厂
refreshBeanFactory();
//返回刷新后的bean工厂
return getBeanFactory();
}
AbstractRefreshableApplicationContext.refreshBeanFactory()
refreshBeanFactory()又是一个抽象方法,ClassPathXmlApplicationContext的继承线上有一个AbstractRefreshableApplicationContext的抽象实现类里对它进行了重写,看下它的实现
@Override
protected final void refreshBeanFactory() throws BeansException {
//如果bean工厂已经存在
if (hasBeanFactory()) {
//删除所有单例bean
destroyBeans();
//销毁原有bean工厂
closeBeanFactory();
}
try {
//默认创建的bean工厂 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//两个配置项
//setAllowBeanDefinitionOverriding
// 默认true,允许同名bean进行覆盖,后出现的bean会覆盖前面出现的同名bean
// 如果设置为false,出现同名bean会报错提示
//setAllowCircularReferences
// 默认true,允许循环依赖,构造器依赖spring无法处理
customizeBeanFactory(beanFactory);
//加载XML里的bean配置
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
AbstractApplicationContext.loadBeanDefinitions()
此处未直接去加载相关的配置,而是将配置文件交给了一个XmlBeanDefinitionReader类去处理,这是根据单一职责的设计原则将不同的事情交给不同的类来处理,整个方法就是创建了一个reader,reader里持有了beanFactory的引用,reader去解析xml配置,将解析完的数据存放到beanFactory里
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//创建一个beanXml解析器
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);
//加载bean定义
loadBeanDefinitions(beanDefinitionReader);
}
AbstractApplicationContext.loadBeanDefinitions()
这是一个overwrite方法,只干了一件事,获取已知的 文件路径,按路径进行解析
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//获得刚才传入的配置文件地址configLocations
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
AbstarctBeanDefinitionReader.loadBeanDefinitions()
循环已知路径,进行解析,最终会交给对应的XmlBeanDefinitionReader来处理
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;
}
XmlBeanDefinitionReader.loadBeanDefinitions()
这里将文件读取为文件流,进行格式转码等前置操作,将其扔给doLoadBeanDefinitions()里进行执行,在Spring的源码里有个特点 ,叫doXXX()的方法通常都是真正去做业务处理的方法, 这点后面可以留意
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (logger.isTraceEnabled()) {
logger.trace("Loading XML bean definitions from " + encodedResource);
}
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
//按路径将文件读取为输入流
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//真正的解析方法
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
XmlBeanDefinitionReader.doLoadBeanDefinitions()
将流对象包装为一个Document对象,扔到registerBeanDefinitions()里处理
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//获取配置的doc文档
Document doc = doLoadDocument(inputSource, resource);
//根据doc文档内容注册beanDefinition
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (SAXParseException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
}
catch (SAXException ex) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(),
"XML document from " + resource + " is invalid", ex);
}
catch (ParserConfigurationException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Parser configuration exception parsing XML from " + resource, ex);
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"IOException parsing XML document from " + resource, ex);
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(resource.getDescription(),
"Unexpected exception parsing XML document from " + resource, ex);
}
}
XmlBeanDefinitionReader.registerBeanDefinitions()
创建一个文档阅读器,将上一步生成的文档传给文档阅读器进行解析,解析完成后将beanDefinition对象注册,并返回本次让beanDenition对象产生了多少数量的变化
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//创建文档阅读器
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//注册前的beanDefinition数量
int countBefore = getRegistry().getBeanDefinitionCount();
//注册beanDefinition
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
//返回数量变化
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions()
这个类本身是一个文档阅读器,因此spring在设计中,这个类的功能就是解析文档内容,因此注册BeanDefinition对象的事件,它交给了一个委托对象,由BeanDefinitionParserDelegate来处理注册相关的事情
protected void doRegisterBeanDefinitions(Element root) {
// Any nested <beans> elements will cause recursion in this method. In
// order to propagate and preserve <beans> default-* attributes correctly,
// keep track of the current (parent) delegate, which may be null. Create
// the new (child) delegate with a reference to the parent for fallback purposes,
// then ultimately reset this.delegate back to its original (parent) reference.
// this behavior emulates a stack of delegates without actually necessitating one.
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
// We cannot use Profiles.of(...) since profile expressions are not supported
// in XML config. See SPR-12458 for details.
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isDebugEnabled()) {
logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
}
}
//模板方法
preProcessXml(root);
//解析bean定义并进行注册
parseBeanDefinitions(root, this.delegate);
//模板方法,spring里这种前后置的模板方法运用的非常多
postProcessXml(root);
this.delegate = parent;
}
DefaultBeanDefinitionDocumentReader.parseBeanDefinitions()
解析对应的元素
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//解析默认元素
parseDefaultElement(ele, delegate);
}
else {
//解析自定义元素
delegate.parseCustomElement(ele);
}
}
}
}
else {
//解析自定义元素,这个方法应该是由解析如import类的文件使用
delegate.parseCustomElement(root);
}
}
DefaultBeanDefinitionDocumentReader.parseDefaultElement()
对默认支持的bean import 等XML标签进行解析
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
//解析import进来的文件
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
//处理别名注册
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
//解析beanDefinition的定义
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// 进行嵌套对象的解析
doRegisterBeanDefinitions(ele);
}
}
DefaultBeanDefinitionDocumentReader.processBeanDefinition()
这里会将文档内的定义,每一个<bean>包装成一个BeanDefinition对象,再由一个BeanDefinitionHolder来包装,具体的解析细节后面会单独抽一章来写,此处不做扩展
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
//将解析完的XML文档包装到一个BeanDefinitionHolder中
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// Register the final decorated instance.
//最终注册逻辑
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// Send registration event.
//发送注册事件
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
BeanDefinitionReaderUtils.registerBeanDefinition()
最终进行BeanDefinition与别名的注册
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
//注册beanDefinition对象
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
//注册别名
registry.registerAlias(beanName, alias);
}
}
}
IOC流程(二)初始化
到上面,一个简单的BeanDefinition对象就已经加载完成了,那么这个定义在什么时候被Spring使用了呢?回到AbstractApplicationContext的refresh()方法中,看下
@Override
public void refresh() throws BeansException, IllegalStateException {
....
// Instantiate all remaining (non-lazy-init) singletons.
//初始化非懒加载的单例bean
finishBeanFactoryInitialization(beanFactory);
....
AbstractApplicationContext.finishBeanFactoryInitialization()
重点关注最后的一个方法 beanFactory.preInstantiateSingletons();
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();
// Instantiate all remaining (non-lazy-init) singletons.
//单懒加载的单例bean开始实例化
beanFactory.preInstantiateSingletons();
}
DefaultListableBeanFactory.preInstantiateSingletons()
在这里规定了,抽象的,非单例的,懒加载的bean本次不会处理
对于beanFactory对象前面加上&就可以拿到bean的工厂对象,也是在源码里写死的,下面的注释里可以看到,后续会知道,@Bean就是通过beanFactory的方式来创建Bean实例的,这里不多做解释
getBean()方法会调用doGetBean()方法,执行bean获取逻辑
public void preInstantiateSingletons() throws BeansException {
if (logger.isTraceEnabled()) {
logger.trace("Pre-instantiating singletons in " + this);
}
// 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.
//之前扫描的beanNames进行循环
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
//合并父子对象 即带有parent标签的对象
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
//只有非抽象,单例,非懒加载的对象进行实例化逻辑
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//工厂bean创建
if (isFactoryBean(beanName)) {
//前端加上&号就可以拿到FactoryBean的实例,即加工指定Bean的工厂bean
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 {
//非工厂bean的实例化路线
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();
}
}
}
}
AbstractBeanFactory.doGetBean()
这里的方法非常多,重点看几个,
一是在入口处调用了 Object sharedInstance = getSingleton(beanName);从缓存内拿到已经实例化过的对象,保证单例,并且在这里使用了三级缓存,解决了单例循环依赖问题(需要注意的是,构造方法式的依赖注入,无法通过三级缓存解决)
二是解决了dependsOn优先实例化被依赖对象的问题
三是根据BeanDefinition的描述,创建各类bean对象
这里我们重点看单例bean实例化的方法 createBean(beanName, mbd, args);
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;
// Eagerly check singleton cache for manually registered singletons.
//从缓存里获取bean对象,也是在这里解决了循环依赖问题
Object sharedInstance = getSingleton(beanName);
....省略部分代码
//如果Prototype类型出现的循环引用,直接抛出异常
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
....省略部分代码
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
....省略部分代码
//注册被依赖的bean
registerDependentBean(dep, beanName);
try {
//优先获取依赖的bean
getBean(dep);
}
....省略部分代码
// 创建单例bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
//单例bean创建
return createBean(beanName, mbd, args);
}
....省略部分代码
//Prototype类型bean创建
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
//Prototype类型bean创建
prototypeInstance = createBean(beanName, mbd, args);
}
....省略部分代码
return (T) bean;
}
AbstractAutowireCapableBeanFactory.createBean()
这里有几点
一是处理了MethodOverride方法
二是提供了一个创建bean对象代理类的入口 ,AOP的动态代理就是在这里创建的
调用doCreateBean(beanName, mbdToUse, args);方法创建bean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
//创建一个RootBeanDefinition
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
//给实例一个返回代理对象的机会 ,AOP创建动态代理就是走的这里
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//创建bean对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
AbstractAutowireCapableBeanFactory.doCreateBean()
这里调用了createBeanInstance创建bean实例
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
....省略部分代码
}
AbstractAutowireCapableBeanFactory.createBeanInstance()
无参实例化调用 instantiateBean方法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
...省略部分代码
// No special handling: simply use no-arg constructor.
//常规的无参实例化
return instantiateBean(beanName, mbd);
}
AbstractAutowireCapableBeanFactory.instantiateBean()
无参实例化调用 instantiateBean方法
try {
Object beanInstance;
final BeanFactory parent = this;
if (System.getSecurityManager() != null) {
beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
getInstantiationStrategy().instantiate(mbd, beanName, parent),
getAccessControlContext());
}
else {
//获取实例化策略进行实例化
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
}
SimpleInstantiationStrategy.instantiate()
调用BeanUtils.instantiateClass(constructorToUse)进行实例化
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (!bd.hasMethodOverrides()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(
(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
}
else {
constructorToUse = clazz.getDeclaredConstructor();
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Throwable ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
//实例化bean对象
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
BeanUtils.instantiateClass()
终于走到newInstance了,对了,可以放心大胆的说IOC是通过反射来完成的了,它就是用的反射!
public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
//设置反射的构造器
ReflectionUtils.makeAccessible(ctor);
//kotlin的支持
if (KotlinDetector.isKotlinReflectPresent() && KotlinDetector.isKotlinType(ctor.getDeclaringClass())) {
return KotlinDelegate.instantiateClass(ctor, args);
}
else {
Class<?>[] parameterTypes = ctor.getParameterTypes();
Assert.isTrue(args.length <= parameterTypes.length, "Can't specify more arguments than constructor parameters");
Object[] argsWithDefaultValues = new Object[args.length];
for (int i = 0 ; i < args.length; i++) {
if (args[i] == null) {
Class<?> parameterType = parameterTypes[i];
argsWithDefaultValues[i] = (parameterType.isPrimitive() ? DEFAULT_TYPE_VALUES.get(parameterType) : null);
}
else {
argsWithDefaultValues[i] = args[i];
}
}
//创建对应实例,并将前面解析的参数装载进去
return ctor.newInstance(argsWithDefaultValues);
}
}
catch (InstantiationException ex) {
throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);
}
catch (IllegalAccessException ex) {
throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);
}
catch (IllegalArgumentException ex) {
throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);
}
catch (InvocationTargetException ex) {
throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());
}
总结
其实这将近三万字的代码里 只是做了最简单的反射实例化,像循环依赖的解决,生命周期函数的调用等等都没有涉及到,这里简单的走一遍只是为了建立一个概念,即Spring的IOC本质上只干两件事
一、解析你给的配置信息,无论它是XML的也好,还是注解的也好,最终会将你对bean以及bean关系的描述包装为一个BeanDefinition注册到BeanDefinitionRegisity中
二、根据你的BeanDefinitionRegisity中注册的相关BeanDefinition描述,按你的要求将所有的Bean实例化出来,并将对应的内容注入到对象中(本章未追相关代码)
上一篇: Spring学习一-Spring概述、初识 IOC
下一篇: druid配置项