Spring IoC bean 的加载
2021-05-04 16:30
标签:OLE 实体 integer ioc 回调 amp 了解 rri 曝光 本系列全部基于 本篇文章主要介绍 Spring IoC 容器是怎么加载 我们先看一下Spring IoC BeanDefinition 的加载和注册一文中获取 通过 在正式开始之前,我们先了解一下 当配置文件中 首先定义一个 上面的实体类,如果用传统方式配置,每一个属性都会对应一个 接下来,我们在 XML 中配置。 最后看下测试代码和运行结果: 可以看到如果 上面方法就是获取 上面方法主要就是尝试从缓存中获取 上面代码总结起来就是:如果 下文将合并后的 上面代码主要是获取 首先从缓存中获取 不存在或者已过期的 注意:这里只有 如果没有设置作用域,默认作用域为 缓存 上文中提到如果 首先定义一个 然后我们在 XML 文件中配置一下,如下: 然后下图是我 Debug 的截图,可以看到 上文还提到了嵌套 在 Spring 中,如果某个 采用上面的配置形式可以保证嵌套 嵌套 下面我们举个A、B的 首先获取A,调用 接着会调用 这个方法又引入了一个跟 我们实现一个 上面的 然后在 XML 中配置 接着我们测试一下。测试类: 说一下我们这里的主要思路,新建了三个线程,查询线程内 结果如下图: 本文主要介绍了 关于 最后,我模仿 Spring 写了一个精简版,代码会持续更新。地址:https://github.com/leisurexi/tiny-spring。 Spring IoC bean 的加载 标签:OLE 实体 integer ioc 回调 amp 了解 rri 曝光 原文地址:https://www.cnblogs.com/leisurexi/p/13194515.html前言
Spring 5.2.2.BUILD-SNAPSHOT
版本。因为 Spring 整个体系太过于庞大,所以只会进行关键部分的源码解析。bean
的。正文
bean
的实例代码:public class BeanDefinitionDemo {
public static void main(String[] args) {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("META-INF/bean-definition.xml");
User user = beanFactory.getBean("user", User.class);
System.err.println(user);
}
}
beanFactory.getBean()
这个方法就获取了在 XML 中定义的 bean
,下面我们就重点分析这个方法背后做了什么操作。FactoryBean
及其用法。FactoryBean 介绍
FactoryBean
接口对于 Spring 框架来说占有重要的地位,Spring 自身就提供了70多个 FactoryBean
的实现。它们隐藏了一下复杂 bean
的细节,给上层应用带来了便利。下面是该接口的定义:public interface FactoryBean
的 class
属性配置的实现类时 FactoryBean
时,通过 getBean()
返回的不是 FactoryBean
本身,而是 FactoryBean#getObject()
所返回的对象,相当于 FactoryBean#getObject()
代理了 getBean()
。下面用简单的代码演示一下:Car
实体类:public class Car {
private Integer maxSpeed;
private String brand;
private Double price;
public Integer getMaxSpeed() {
return maxSpeed;
}
public void setMaxSpeed(Integer maxSpeed) {
this.maxSpeed = maxSpeed;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
}
元素标签。如果用 FactoryBean
的方式实现就会灵活一点,下面通过逗号分隔的方式一次性的为 Car
的所有属性配置值。public class CarFactoryBean implements FactoryBean
@Test
public void factoryBeanTest() {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("META-INF/factory-bean.xml");
Car car = beanFactory.getBean("car", Car.class);
System.out.println(car);
CarFactoryBean carFactoryBean = beanFactory.getBean("&car", CarFactoryBean.class);
System.out.println(carFactoryBean);
}
beanName
前面加上 &
获取的是 FactoryBean
本身,不加获取的 getObject()
返回的对象。
FactoryBean
的特殊之处在于它可以向容器中注册两个 bean
,一个是它本身,一个是 FactoryBean.getObject()
方法返回值所代表的 bean
。bean 的加载
AbstractBeanFactory#getBean
public
bean
的整个流程,下面我们对其调用的其它主要方法来一一分析。转换对应的 beanName
AbstractBeanFactory#transformedBeanName
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
// BeanFactoryUtils.java
public static String transformedBeanName(String name) {
Assert.notNull(name, "‘name‘ must not be null");
// 如果name不是&开头,直接返回
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 去除name的&前缀
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
// SimpleAliasRegistry.java
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
// 如果name是别名,则会循环去查找bean的实际名称
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
尝试从单例缓存获取 bean
AbstractBeanFactory#getSingleton
public Object getSingleton(String beanName) {
// allowEarlyReference设置为true表示允许早期依赖
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从一级缓存中,检查单例缓存是否存在
Object singletonObject = this.singletonObjects.get(beanName);
// 如果为空,并且当前bean正在创建中,锁定全局变量进行处理
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 从二级缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName);
// 二级缓存为空 && bean允许提前曝光
if (singletonObject == null && allowEarlyReference) {
// 从三级缓存中获取bean对应的ObjectFactory
ObjectFactory> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 调用预先设定的getObject(),获取bean实例
singletonObject = singletonFactory.getObject();
// 放入到二级缓存中,并从三级缓存中删除
// 这时bean已经实例化完但还未初始化完
// 在该bean未初始化完时如果有别的bean引用该bean,可以直接从二级缓存中取出返回
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
bean
,缓存有三级,这也是 Spring 解决循环依赖的关键所在;后续会在 循环依赖 中重点讲述。获取 bean 实例对象
AbstractBeanFactory#getObjectForBeanInstance
protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// name 是否以 & 开头
if (BeanFactoryUtils.isFactoryDereference(name)) {
// 如果是 null 直接返回
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// beanName 以 & 开头,但又不是 FactoryBean 类型,抛出异常
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
// 设置 isFactoryBean 为 true
if (mbd != null) {
mbd.isFactoryBean = true;
}
// 返回 bean 实例
return beanInstance;
}
// name 不是 & 开头,并且不是 FactoryBean 类型,直接返回
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
// 到这里就代表name不是&开头,且是FactoryBean类型
// 即获取FactoryBean.getObject()方法返回值所代表的bean
Object object = null;
if (mbd != null) {
mbd.isFactoryBean = true;
}
else {
// 从缓存中获取实例
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// 将 beanInstance 强转成 FactoryBean
FactoryBean> factory = (FactoryBean>) beanInstance;
// 合并 BeanDefinition
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 获取实例
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
// FactoryBeanRegistrySupport.java
protected Object getObjectFromFactoryBean(FactoryBean> factory, String beanName, boolean shouldPostProcess) {
// 如果是单例 bean,并且已经存在缓存中
if (factory.isSingleton() && containsSingleton(beanName)) {
// 加锁
synchronized (getSingletonMutex()) {
// 从缓存中获取
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 调用 FactoryBean 的 getObject() 获取实例
object = doGetObjectFromFactoryBean(factory, beanName);
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
// 如果该 beanName 已经在缓存中存在,则将 object 替换成缓存中的
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (shouldPostProcess) {
// 如果当前 bean 还在创建中,直接返回
if (isSingletonCurrentlyInCreation(beanName)) {
return object;
}
// 单例 bean 创建前回调
beforeSingletonCreation(beanName);
try {
// 对从 FactoryBean 获得给定对象的后置处理,默认按原样返回
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean‘s singleton object failed", ex);
}
finally {
// 单例 bean 创建后回调
afterSingletonCreation(beanName);
}
}
if (containsSingleton(beanName)) {
// 将 beanName 和 object 放到 factoryBeanObjectCache 缓存中
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
// 返回实例
return object;
}
}
else {
// 调用 FactoryBean 的 getObject() 获取实例
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (shouldPostProcess) {
try {
// 对从 FactoryBean 获得给定对象的后置处理,默认按原样返回
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean‘s object failed", ex);
}
}
// 返回实例
return object;
}
}
// FactoryBeanRegistrySupport.java
private Object doGetObjectFromFactoryBean(final FactoryBean> factory, final String beanName) throws BeanCreationException {
Object object;
try {
// 调用 getObject() 获取实例
object = factory.getObject();
}
// 省略异常处理...
// 如果 object 为 null,并且当前 singleton bean 正在创建中,抛出异常
if (object == null) {
if (isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName, "FactoryBean which is currently in creation returned null from getObject");
}
object = new NullBean();
}
// 返回 object 实例
return object;
}
beanName
以 &
开头,直接返回 FactoryBean
实例;否则调用 getObject()
方法获取实例,然后执行 postProcessObjectFromFactoryBean()
回调,可以在回调方法中修改实例,默认按原样返回。合并 bean 定义元信息
AbstractBeanFactory#getMergedLocalBeanDefinition
BeanDefinition
简称为 MergedBeanDefinition
。protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 从缓存获取MergedBeanDefinition
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
// 如果存在MergedBeanDefinition,并且不是过期的,直接返回
if (mbd != null && !mbd.stale) {
return mbd;
}
// 获取已经注册的BeanDefinition然后去合并
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
throws BeanDefinitionStoreException {
// 顶级bean获取合并后的BeanDefinition
return getMergedBeanDefinition(beanName, bd, null);
}
/**
* @param containingBd 如果是嵌套bean该值为顶级bean,如果是顶级bean该值为null
*/
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
throws BeanDefinitionStoreException {
// 加锁
synchronized (this.mergedBeanDefinitions) {
// 本次的RootBeanDefinition
RootBeanDefinition mbd = null;
// 以前的RootBeanDefinition
RootBeanDefinition previous = null;
// 如果bean是顶级bean,直接获取MergedBeanDefinition
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 没有MergedBeanDefinition || BeanDefinition过期了
if (mbd == null || mbd.stale) {
previous = mbd;
// 如果bean没有parent
if (bd.getParentName() == null) {
// 如果bd本身就是RootBeanDefinition直接复制一份,否则创建一个
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
mbd = new RootBeanDefinition(bd);
}
}
else {
// bean有parent
BeanDefinition pbd;
try {
// 获取parent bean的实际名称
String parentBeanName = transformedBeanName(bd.getParentName());
if (!beanName.equals(parentBeanName)) {
// 当前beanName不等于它的parentBeanName
// 获取parent的MergedBeanDefinition
pbd = getMergedBeanDefinition(parentBeanName);
}
else {
// 如果parentBeanName与bd的beanName相同,则拿到父BeanFactory
// 只有在存在父BeanFactory的情况下,才允许parentBeanName与自己相同
BeanFactory parent = getParentBeanFactory();
if (parent instanceof ConfigurableBeanFactory) {
// 如果父BeanFactory是ConfigurableBeanFactory类型
// 则通过父BeanFactory获取parent的MergedBeanDefinition
pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
}
else {
// 如果父BeanFactory不是ConfigurableBeanFactory,抛出异常
throw new NoSuchBeanDefinitionException(parentBeanName,
"Parent name ‘" + parentBeanName + "‘ is equal to bean name ‘" + beanName + "‘: cannot be resolved without an AbstractBeanFactory parent");
}
}
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, "Could not resolve parent bean definition ‘" + bd.getParentName() + "‘", ex);
}
// 使用父MergedBeanDefinition构建一个新的RootBeanDefinition对象(深拷贝)
mbd = new RootBeanDefinition(pbd);
// 覆盖与parent相同的属性
mbd.overrideFrom(bd);
}
// 如果bean没有设置scope属性,默认是singleton
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
// 当前bean是嵌套bean && 顶级bean的作用域不是单例 && 当前bean的作用域是单例
// 这里总结起来就是,如果顶层bean不是单例的,那么嵌套bean也不能是单例的
if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
// 设置当前bean的作用域和顶级bean一样
mbd.setScope(containingBd.getScope());
}
// 当前bean是顶级bean && 缓存bean的元数据(该值默认为true)
if (containingBd == null && isCacheBeanMetadata()) {
// 将当前bean的MergedBeanDefinition缓存起来
this.mergedBeanDefinitions.put(beanName, mbd);
}
}
// 以前的RootBeanDefinition不为空,拷贝相关的BeanDefinition缓存
if (previous != null) {
copyRelevantMergedBeanDefinitionCaches(previous, mbd);
}
return mbd;
}
}
MergedBeanDefinition
,主要步骤如下:
bean
的 MergedBeanDefinition
,如果存在并且未过期直接返回。MergedBeanDefinition
,获取已经注册的 BeanDefinition
去作为顶级 bean
合并。bean
没有 parent
(就是 XML 中的 parent 属性),直接封装成 RootBeanDefinition
。bean
有 parent
,先去获取父 MergedBeanDefinition
,然后覆盖和合并与 parent
相同的属性。
abstract
、scope
、lazyInit
、autowireMode
、dependencyCheck
、dependsOn
、factoryBeanName
、factoryMethodName
、initMethodName
、destroyMethodName
会覆盖,而 constructorArgumentValues
、propertyValues
、methodOverrides
会合并。singleton
。MergedBeanDefinition
。bean
有 parent
,会合并一些属性,这里我们稍微展示一下合并后的 propertyValues
:SuperUser
继承上面定义的 User
,如下:public class SuperUser extends User {
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "SuperUser{" +
"address=‘" + address + ‘\‘‘ +
‘}‘;
}
}
superUser
的 propertyValues
合并了 user
的 id
和 name
属性。bean
,下面我们简单看一下什么是嵌套 bean
。bean
所依赖的 bean
不想被 Spring 容器直接访问,可以使用嵌套 bean
。和普通的 bean
一样,使用 bean
元素来定义嵌套的 bean
,嵌套 bean
只对它的外部 bean
有效,Spring 无法直接访问嵌套 bean
,因此定义嵌套 bean
也无需指定 id
属性。如下配置片段是一个嵌套 bean
示例:bean
不能被容器访问,因此不用担心其他程序修改嵌套 bean
。外部 bean
的用法和使用结果和以前没有区别。
bean
提高了 bean
的内聚性,但是降低了程序的灵活性。只有在确定无需通过 Spring 容器访问某个 bean
实例时,才考虑使用嵌套 bean
来定义。寻找依赖
DefaultSingletonBeanRegistry#isDependent
protected boolean isDependent(String beanName, String dependentBeanName) {
// 加锁
synchronized (this.dependentBeanMap) {
// 检测beanName和dependentBeanName是否有循环依赖
return isDependent(beanName, dependentBeanName, null);
}
}
private boolean isDependent(String beanName, String dependentBeanName, @Nullable Set
DefaultSingletonBeanRegistry#registerDependentBean
public void registerDependentBean(String beanName, String dependentBeanName) {
// 解析别名,获取实际的beanName
String canonicalName = canonicalName(beanName);
// 加锁
synchronized (this.dependentBeanMap) {
// 获取canonicalName依赖beanName集合,如果为空默认创建一个LinkedHashSet当做默认值
Set
depends-on
属性都是对方的例子:isDependent()
方法,因为第一次获取A,所以 dependentBeanMap
中没有记录依赖关系,直接返回 false
;接着调用registerDependentBean()
,这里会向 dependentBeanMap
中反过来存储依赖关系,也就是以B为 key
,value
是一个包含A的 Set
集合。getBean()
方法获取B,首先调用 isDependent()
方法,因为在获取A时已经存储了B的依赖关系,所以获取到的dependentBeans
的集合中包含A,所以直接返回true,抛出循环引用异常。dependentBeanMap
类似的缓存 dependenciesForBeanMap
。这两个缓存很容易搞混,这里再举一个简单的例子:A 依赖 B,那么 dependentBeanMap
存放的是 key
为 B,value
为含有 A 的 Set
;而 dependenciesForBeanMap
存放的是key
为 A,value
为含有 B 的 Set
。创建和注册单例 bean
DefaultSingletonBeanRegistry#getSingleton
public Object getSingleton(String beanName, ObjectFactory> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
// 加锁
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
// 缓存中不存在当前 bean,也就是当前 bean 第一次创建
if (singletonObject == null) {
// 如果当前正在销毁 singletons,抛出异常
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)");
}
// 创建单例 bean 之前的回调
beforeSingletonCreation(beanName);
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
// 获取 bean 实例,在此处才会去真正调用创建 bean 的方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
// 省略异常处理...
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
// 创建单例 bean 之后的回调
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 将 singletonObject 放入缓存
addSingleton(beanName, singletonObject);
}
}
// 返回 bean 实例
return singletonObject;
}
}
// 单例 bean 创建前的回调方法,默认实现是将 beanName 加入到当前正在创建 bean 的缓存中,
// 这样便可以对循环依赖进行检测
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
// 单例 bean 创建后的回调方法,默认实现是将 beanName 从当前正在创建 bean 的缓存中移除
protected void afterSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)) {
throw new IllegalStateException("Singleton ‘" + beanName + "‘ isn‘t currently in creation");
}
}
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// 这边bean已经初始化完成了,放入一级缓存
this.singletonObjects.put(beanName, singletonObject);
// 移除三级缓存
this.singletonFactories.remove(beanName);
// 移除二级缓存
this.earlySingletonObjects.remove(beanName);
// 将 beanName 添加到已注册 bean 缓存中
this.registeredSingletons.add(beanName);
}
}
自定义作用域示例
ThreadLocal
级别的作用域,也就是同一个线程内 bean
是同一个实例,不同线程的 bean
是不同实例。首先我们继承 Scope
接口实现,其中方法。如下:public class ThreadLocalScope implements Scope {
/** scope 名称,在 XML 中的 scope 属性就配置此名称 */
public static final String SCOPE_NAME = "thread-local";
private final NamedThreadLocal
ThreadLocalScope
重点关注下 get()
即可,该方法是被 Spring 调用的。bean
的 scope
为 thread-local
。如下:@Test
public void test() throws InterruptedException {
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
// 注册自定义作用域
beanFactory.registerScope(ThreadLocalScope.SCOPE_NAME, new ThreadLocalScope());
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
reader.loadBeanDefinitions("META-INF/custom-bean-scope.xml");
for (int i = 0; i {
User user = beanFactory.getBean("user", User.class);
System.err.printf("[Thread id :%d] user = %s%n", Thread.currentThread().getId(), user.getClass().getName() + "@" + Integer.toHexString(user.hashCode()));
User user1 = beanFactory.getBean("user", User.class);
System.err.printf("[Thread id :%d] user1 = %s%n", Thread.currentThread().getId(), user1.getClass().getName() + "@" + Integer.toHexString(user1.hashCode()));
});
thread.start();
thread.join();
}
}
user bean
是否相等,不同线程是否不等。总结
getBean()
方法流程,我们可以重新梳理一下思路:
bean
实际名称,如果缓存中存在直接取出实际 bean
返回。BeanDefinition
,没有递归去父工厂创建 bean
。BeanDefinition
,如果 depends-on
不为空,先去初始化依赖的 bean
。bean
的作用域是单例,调用 createBean()
方法创建实例,这个方法会执行 bean
的其它生命周期回调,以及属性赋值等操作;接着执行单例 bean
创建前后的生命周期回调方法,并放入 singletonObjects
缓存起来。bean
的作用域是原型,调用 createBean()
方法创建实例,并执行原型 bean
前后调用生命周期回调方法。bean
的作用域是自定义的,获取对应的 Scope
对象,调用重写的 get()
方法获取实例,并执行原型 bean
前后调用生命周期回调方法。bean
实例的类型匹配,如果不等进行转换,最后返回实例。createBean()
方法的细节,会在后续文章中进行分析。
参考
文章标题:Spring IoC bean 的加载
文章链接:http://soscw.com/index.php/essay/82350.html