<div class="content" id="articleContent">
<div class="ad-wrap">
<p><a href="https://my.oschina.net/u/2663968/blog/3061697" style="color:#A00;font-weight:bold;">2019独角兽企业重金招聘Python工程师标准>>> </a> <img alt="hot3.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-cf0d92129138e2c138e143696168013a.png"></p>
</div>
<span id="OSC_h2_1"></span>
<h2><strong>前言</strong></h2>
<p> 上一节讲到了,Spring 会根据实例的作用域执行不同的创建逻辑,分别是 Singleton、Prototype、其他 Scope,其中 Singleton 会调用 getSingleton 从缓存中获取,缓存中没有才会创建实例;Prototype 每次都会创建;其他 Scope 会调用 Scope.get 获取,保证各作用域内实例唯一。</p>
<p> 它们的公共创建逻辑都是 <span style="color:#c0392b;">createBean </span>方法。</p>
<p> </p>
<span id="OSC_h2_2"></span>
<h2><strong>源码解读</strong></h2>
<p> <span style="color:#c0392b;">createBean </span>方法由 <span style="color:#c0392b;">AbstractAutowireCapableBeanFactory </span>实现。</p>
<pre class="blockcode"><code class="language-java">public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
// bean默认实例化策略 —— Ciglib增强代理
private InstantiationStrategy instantiationStrategy =
new CglibSubclassingInstantiationStrategy();
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 解析获取 bean对应类的 Class对象,并拷贝一份 RootBeanDefinition
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
/**
* 对于 methodOverrides的校验,即 lookup-method和 replaced-method
* 如果指定的方法不存在,会抛出异常
*/
try {
mbdToUse.prepareMethodOverrides();
} catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 让 BeanPostProcessors有机会返回代理而不是目标 bean实例
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);
}
// 创建目标 bean实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
}</code></pre>
<p> 首先会解析出要创建实例的类型,之后是对 <span style="color:#c0392b;">methodOverrides </span>的校验</p>
<ul><li><span style="color:#c0392b;">lookup-method </span>:用于将 bean 的指定方法(name属性),配置指定返回哪些实例(bean属性);</li><li><span style="color:#c0392b;">replaced-method</span> :用于将 bean 的指定方法(name属性),替换为——“实现<span style="color:#c0392b;">MethodReplacer</span>”的对象(replacer属性),即方法替换为实现的 <span style="color:#c0392b;">reimplement </span>方法。</li></ul>
<p> 这些替换的前提就是,被指定的方法一定要存在,这就是校验的目的。之后就有两条线了,一个是代理路线(<span style="color:#c0392b;">resolveBeforeInstantiation</span>),另一个是常规的实例创建路线(<span style="color:#c0392b;">doCreateBean</span>)。</p>
<p> </p>
<span id="OSC_h4_3"></span>
<h4><strong>resolveBeforeInstantiation</strong></h4>
<pre class="blockcode"><code class="language-java"> protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// 判断 bean是否为合成的(即不是应用本身定义的),例如 <aop-config>创建的
// 判断全局是否注册有 InstantiationAwareBeanPostProcessor(BeanPostProcessor子类)
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
// 获取 bean的目标类型
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != nu |
|