1、装载bean的第一步,调用doGetBean(name,...)方法
(1)转换对应的beanName,参数里面的name未必是beanName,可能是别名或者factoryBean
(2)首先尝试从缓存中加载单例
(3)如果从缓存中拿到了bean,调用getObjectForBeanInstance 将bean实例化
(4)原型模式依赖检查
(5)通过getParentBeanFactory获取parentBeanFactory
(6)获取RootBeanDefinition
(7)针对不同的scope进行bean的创建
(8)类型转换
2、从缓存中获取单例对象,其中,
singletonObjects是一个map,存储实例化后的对象
earlySingletonObjects也是一个map,存储实例化后的对象,与singletonObjects的区别是,当一个单例的bean被放到这个map中以后,当bean还在创建中的时候就可以通过getbean获取到了,用来检测循环引用
singletonFactories:保存beanName和创建bean的工厂之间的映射关系
registeredSingletons:保存当前所有已经注册的bean
3、根据不同的scope创建bean, 以单例为例:getSingleton()方法的第一个参数是beanName, 第二个参数是一个接口:ObjectFactory,这个接口提供一个getObject方法在getSingleton中的singletonObject = singletonFactory.getObject();时候使用。
下面看getObject的时候都做了什么
getObject会使用AbstractBeanFactory类的抽象方法:
protected abstract Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException;
他的实现写在AbstractAutowireCapableBeanFactory里面,继承结构图如下:
4、createBean进去以后首先找到BeanDefinition,然后调用doCreateBean()创建真正的bean,doCreateBean中完成了以下几件事:
(1)如果需要创建的bean是单例,需要首先清除缓存
(2)实例化bean,调用createBeanInstance()方法,将beanDefinition转化为BeanWrapper
这个过程包含以下几个步骤
- 如果存在工厂方法,则使用工厂方法进行初始化
- 当一个类有多个构造函数的时候,每个构造函数都有不同的参数,需要根据参数锁定构造函数并进行初始化
- 如果即不存在工厂方法,也不存在带有参数的构造方法,使用默认构造方法进行bean的实例、
(3)调用populateBean进行属性的填充
(4)调用registerDisposableBeanIfNecessary进行bean的注册
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args); //创建beanWrapper
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
mbd.postProcessed = true;
}
}
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); //属性注入
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd); //调用初始化方法
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
......
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd); //注册bean
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
5、使用createBeanInstance创建bean实例
获取beanName对应的class
- 如果存在工厂方法,使用工厂方法执行bean的初始化策略
- 解析构造函数并进行构造函数的实例化
里面比较重要的方法是
autowireConstructor(beanName, mbd, null, null);(调用带有参数的构造方法)和instantiateBean(beanName, mbd);(调用无参构造方法)
6、使用populateBean进行属性注入
该方法中最重要的是对autowireByName(beanName, mbd, bw, newPvs);和对autowireByType(beanName, mbd, bw, newPvs);方法的调用,
最后再使用applyPropertyValues(beanName, mbd, bw, pvs); 将所有的属性填充到BeanWrapper中
(4)getBean方法中无论是要创建那种类型的bean最终都是通过getObjectForBeanInstance(...)方法生成,该方法是beanFactory与factoryBean的桥梁,在这个方法中调用BeanFactory通过factoryBean去创建bean
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
//如果bean不是一个FactoryBean则不做任何处理
if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass());
}
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
if (mbd == null && containsBeanDefinition(beanName)) {
mbd = getMergedLocalBeanDefinition(beanName);
}
boolean synthetic = (mbd != null && mbd.isSynthetic());
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
(3)getObjectFromFactoryBean
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
}
this.factoryBeanObjectCache.put(beanName, (object != null ? object : NULL_OBJECT));
}
}
return (object != NULL_OBJECT ? object : null);
}
}
else {
Object object = doGetObjectFromFactoryBean(factory, beanName);
if (object != null && shouldPostProcess) {
try {
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
(4)doGetObjectFromFactoryBean
private Object doGetObjectFromFactoryBean(final FactoryBean<?> factory, final String beanName)
throws BeanCreationException {
Object object;
try {
if (System.getSecurityManager() != null) {
AccessControlContext acc = getAccessControlContext();
try {
object = AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
@Override
public Object run() throws Exception {
return factory.getObject();
}
}, acc);
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
object = factory.getObject();
}
}
catch (FactoryBeanNotInitializedException ex) {
throw new BeanCurrentlyInCreationException(beanName, ex.toString());
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation", ex);
}
// Do not accept a null value for a FactoryBean that's not fully
// initialized yet: Many FactoryBeans just return null then.
if (object == null && isSingletonCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(
beanName, "FactoryBean which is currently in creation returned null from getObject");
}
return object;
}
相关推荐
本文深入探讨了Spring框架中IoC容器的源码机制,涵盖了容器的初始化、Bean工厂的实例化、Bean定义的读取及Spring Bean的生命周期管理。通过精细的分析,本文揭示了AnnotationConfigApplicationContext的实例化过程,...
springframework 是sping 里面的一个开源框架...它实现了很优雅的MVC,对不同的数据访问技术提供了统一的接口,采用IOC使得可以很容易的实现bean的装配,提供了简洁的AOP并据此实现Transaction Management,等等......
本文深入探讨了Spring IoC容器的加载过程及其源码实现,揭示了Spring中最为根本的概念之一。这包括从AnnotationConfigApplicationContext的实例化开始,到DefaultListableBeanFactory工厂的建立,再到...
1、 需要去构造一个Spring容器:ClassPathXmlApplicationContext; 2、 需要注解定义两个注解:@Service、@Resource; 3、 使用反射的手段读取指定目录下的class信息,解析Class信息; 4、 对Class信息的注解做处理...
它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC,DI(控制反转Inversion of Control ,DI:Dependency Injection 依赖注入)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制...
com-spring-ioc-demo:源码主要是学习Spring IOC的原理,以及对Bean的注册及控制,主要运用以下类对Spring进行扩展学习:BeanPostProcessor,BeanFactoryAware,BeanNameAware,ApplicationContextAware,FactoryBean...
它提供了一组可以在Spring应用上下文中配置的Bean,充分利用了Spring IoC(依赖注入,也称控制反转)和AOP(面向切面编程)功能,为应用系统提供声明式的安全访问控制功能,减少了为企业系统安全控制编写大量重复...
学习Spring过程中,使用Eclipse调试Spring源码的关键断点文件。
SpringIOC示例源代码,包括bean.xml配置文件等信息。
2、SpringIOC体系结构 3、源码分析-IOC容器的初始化 4、源码分析-IOC容器的依赖注入 5、源码分析-IOC容器的高级特性 三阶段 Spring AOP的涉及原理及具体实践 SpringJDBC的涉及原理及二次开发 SpringMVC框架设计原理...
1. bean的装配方式 1.表明当前类是一个配置类,是方法bean的源 2.将@Configuration配置的AppConfig的BeanDefinitio
Spring 源码分析(Bean的初始化) 前言 本篇文章是个人第一次看spring源码并总结,同时也参考了下面这篇博客。基本也是按照他的思路来理解的。这也算是第一版个人简易理解。也算是窥见spring的冰山一角,之后也会...
spring ioc 源码解析图,全网最细、最全的源码解析讲解,关于spring bean创建过程原理解析、循环依赖原理解析等等等
提供了Spring容器的支持,扩展了BeanFactory,提供了Spring中Bean生命周期的支持,在bean创建完成之后, 也是由该模块负责来维护bean和bean之间的依赖关系。常用的ApplicationContext核心接口也是该模块中所支持的;...
2.5 使用Spring IDE的Bean-supporting特性 2.5.1 问题描述 2.5.2 解决方案 2.5.3 实现方法 2.6 小结 第3章 Spring中的Bean配置 3.1 在Spring IoC容器里配置Bean 3.1.1 问题...
想看源码但是Spring的源码层次复杂,封装繁琐,简单的逻辑写的非常“啰嗦”,阅读起来很费劲。然后发现了多年前的一个精简版的Spring学习项目,叫,作者对spring核心的IOC和AOP进行了临摹实现,也很细心的对实现步骤...
该源码是课程 Java Spring案例精讲 ---- Spring框架 的源码,包含Java Spring的最简单的Hello World、IOC、AOP及Log的源码 Spring整体框架中的核心功能,例如:IOC、AOP、Bean生命周期、上下文、作用域、资源处理等...
有关于Spring,我们最常用的两个功能就是IOC和AOP,前几篇文章从源码级别介绍了Spring容器如何为我们生成bean及bean之间的依赖关系 下面我们接着来看AOP的源码实现。 有关于AOP,我们在面试中也被无数次问到...
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * @author :xiaolinzi * @date :2020-4-14 20:46 * @email : xiaolinzi95_27@163....