`
darkjune
  • 浏览: 301751 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

简单的Spring的bean实例化过程

阅读更多

以XmlBeanFactory为例,最简单的取bean方式是:

 

BeanFactory factory = new XmlBeanFactory(new FileSystemResource("D:\\workspace\\JavaApplication2\\src\\javaapplication2\\spring\\beans.xml"));
            Car obj = (Car)factory.getBean("car");

 Bean的配置文件内容也很简单:

 

 

    <bean id="vehicle"   abstract="true">
        <property name="wheel" value="Four wheeler"/>        
    </bean>
    <bean id="car" class="javaapplication2.spring.Car" parent="vehicle">
        <property name="dicky" value="Flat dicky"/>    
    </bean>

 

 

先看起始点,载入先走AbstractBeanFactory

 

	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null, null, false);
	}

 

 

 

doGetBean方法中:

 

// Create bean instance.
if (mbd.isSingleton()) {
         //传入一个内联类ObjectFactory并实现了getObject方法。
         sharedInstance = getSingleton(beanName, new ObjectFactory() {
	public Object getObject() throws BeansException {
	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); //有异常则销毁bean
			throw ex;
	}
}
});
	bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
        //此处开始实例化bean

 

 

}

通过new ObjectFactory()的回调方法,回调当前类继承的createBean方法,该方法在父类AbstractAutowireCapableBeanFactory中:

AbstractAutowireCapableBeanFactory->

 

protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {

		// Make sure bean class is actually resolved at this point.
		resolveBeanClass(mbd, beanName);  //载入该bean的class,并放置到mbd里面,bean的生成不在这里。

		// Prepare method overrides.
		try {
			mbd.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbd.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbd);  //尝试获取一个proxy,普通bean这里一般是空的返回
			
			if (bean != null) {
				return bean;
			}
		}
		catch (Throwable ex) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"BeanPostProcessor before instantiation of bean failed", ex);
		}

		Object beanInstance = doCreateBean(beanName, mbd, args);  //开始create bean的实例,mbd中包括了需要的class
		if (logger.isDebugEnabled()) {
			logger.debug("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}

 

 

进入AbstractBeanFactory中的protected Class resolveBeanClass方法:

 

try {
	if (mbd.hasBeanClass()) {
		return mbd.getBeanClass();
	}
	if (System.getSecurityManager() != null) {
		return AccessController.doPrivileged(new PrivilegedExceptionAction<Class>() {
			public Class run() throws Exception {
				return doResolveBeanClass(mbd, typesToMatch);
			}
		}, getAccessControlContext());
	}
	else {
		return doResolveBeanClass(mbd, typesToMatch);   <---还要继续进去看生成方法。
	}
}

 

 

转入doResolveBeanClass:

 

private Class doResolveBeanClass(RootBeanDefinition mbd, Class... typesToMatch) throws ClassNotFoundException {
	if (!ObjectUtils.isEmpty(typesToMatch)) {
		ClassLoader tempClassLoader = getTempClassLoader();
		if (tempClassLoader != null) {
			if (tempClassLoader instanceof DecoratingClassLoader) {
				DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
			for (Class<?> typeToMatch : typesToMatch) {
				dcl.excludeClass(typeToMatch.getName())
			}
		}
		String className = mbd.getBeanClassName();
		return (className != null ? ClassUtils.forName(className, tempClassLoader) : null); //通过自己的ClassUtils的forName方法来实例化class
		}
	}
	return mbd.resolveBeanClass(getBeanClassLoader());  <----这里传入了bean的classloader,下面继续看这里
}

 

 

 

 

 

AbstractBeanDefinition->resolveBeanClass

public Class resolveBeanClass(ClassLoader classLoader) throws ClassNotFoundException {
		String className = getBeanClassName();
		if (className == null) {
			return null;
		}
		Class resolvedClass = ClassUtils.forName(className, classLoader);//classloader传入后,仍然是用forName方法加载class
		this.beanClass = resolvedClass;
		return resolvedClass;
	}

 

再来看forName做了些什么

ClassUtils ->

ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
	classLoaderToUse = getDefaultClassLoader();
}
try {
	return classLoaderToUse.loadClass(name); //也比较简单,直接调用loadClass方法加载
}

 

最终将class load进来。

 

 

Bean实例化过程:

AbstractAutowireCapableBeanFactory->createBeanInstance

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) 
	// Need to determine the constructor...
	//提取构造函数,如果没有就是空
	Constructor[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
			return autowireConstructor(beanName, mbd, ctors, args);
	}

	// No special handling: simply use no-arg constructor.
	return instantiateBean(beanName, mbd); //这里实例化

 

进入

AbstractAutowireCapableBeanFactory->instantiateBean

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd)
...这里省略没用的		
	else {
		beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);//下面看这里的实例化
	}		
			
	BeanWrapper bw = new BeanWrapperImpl(beanInstance);   //返回一个包装类对象
	initBeanWrapper(bw);
	return bw;

 

 

SimpleInstantiationStrategy->instantiate

public Object instantiate(RootBeanDefinition beanDefinition, String beanName, BeanFactory owner)
	synchronized (beanDefinition.constructorArgumentLock) {
			constructorToUse = (Constructor<?>) beanDefinition.resolvedConstructorOrFactoryMethod;
		...
	}
	return BeanUtils.instantiateClass(constructorToUse);	 //BeanUtils来初始化实例 ,给出了实例化需要的构造函数

 

再来看BeanUtils的实例化方法,比较简单,直接用反射的构造函数来newInstance。

BeanUtils->

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
	try {
		ReflectionUtils.makeAccessible(ctor);
		return ctor.newInstance(args);
	}

 

 

AbstractAutowireCapableBeanFactory->

Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 

	// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
	return exposedObject;		//返回给AbstractBeanFactory

 

 

2
5
分享到:
评论

相关推荐

    Spring Bean实例化实现过程解析

    主要介绍了Spring Bean实例化实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    详解Spring中bean实例化的三种方式

    本篇文章主要介绍了详解Spring中bean实例化的三种方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

    Spring bean对象实例化实现过程图解

    主要介绍了Spring bean对象实例化实现过程图解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

    Spring实例化bean过程解析及完整代码示例

    主要介绍了Spring实例化bean过程解析及完整代码示例,简单分析实例化bean过程并且分享了相关实例,具有一定借鉴价值,需要的朋友可以参考下

    Spring工厂方法创建(实例化)bean实例代码

    主要介绍了Spring工厂方法创建bean实例代码,具有一定借鉴价值,需要的朋友可以参考下

    Spring中实例化bean的四种方式详解

    主要给大家介绍了关于Spring中实例化bean的四种方式,分别是setter 方法、构造函数、静态工厂以及实例工厂等四种方法,分别给出了示例代码供大家参考学习,需要的朋友们下面随着小编来一起学习学习吧。

    spring源码底层解析(1.81G)

    【课程介绍】:Spring启动时读取应用提供的Bean配置信息,在Spring容器中生成对应的Bean配置注册表...从源码证明springbean的实例化过程.mp44.spring的核心getSingleton方法.mp45.springbean的生成与循环依赖.mp46.getB

    深入解析Spring IoC源码:核心机制与实践应用

    通过精细的分析,本文揭示了AnnotationConfigApplicationContext的实例化过程,详细解读了DefaultListableBeanFactory的作用及其在Bean生产和获取中的关键性作用。同时,本文对Spring Bean的生命周期进行了深入剖析...

    深入解析Spring IoC:源码与实践指南

    同时,本文还探讨了Spring Bean的生命周期,重点在于Bean容器的创建与Bean的初始化过程。这些深入的分析不仅有助于理解Spring的内部工作机制,而且对于Java开发者来说,能够更好地掌握如何有效地使用Spring框架进行...

    08-IoC配置-bean的生命周期控制

    通过构造器或工厂方法创建Bean实例 为Bean的属性设置值和对其它Bean的引用 调用Bean的初始化方法 Bean可以使用了 当容器关闭时,调用Bean的销毁方法 在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 ...

    基于java的企业级应用开发:Bean的生命周期.ppt

    (1)根据配置情况调用Bean构造方法或工厂方法实例化Bean。 (2)利用依赖注入来完成Bean中所有属性值的配置注入。 (3)如果Bean实现了BeanNameAware接口,则Spring调用Bean的setBeanName()方法传入当前Bean的id值...

    spring源码14: 实例化 无参构造器

    bean的实例化实质就是调用构造函数的过程。构造函数分为有参数的构造函数和无参数的构造函数,对比起无参数构造函数,有参数构造函数将大量的工作花在了挑选最合适的构造函数的过程中,并非是核心所在,因此本篇只讲...

    Spring系列之依赖注入的三种方式.docx

    对于spring配置一个bean时,如果需要给该bean提供一些初始化参数,则需要通过依赖注入方式,所谓的 依赖注入就是通过spring将bean所需要的一些参数传递到bean实例对象的过程(将依赖关系注入到对象中) ,spring的...

    spring.doc

    3.3.2使用静态工厂方法实例化(简单工厂模式) 14 3.3.3初始化(创建)bean时机 15 Lazy-init初始化bean的时机拓展: 15 3.4 Bean的作用域 16 Scope单例多例作用域拓展: 16 3.4.1 singleton(默认值) 16 3.4.2 prototype...

    Spring 3 Reference中文

    4.3.2 实例化bean . 36 4.3.2.1 使用构造方法实例化 36 4.3.2.2 使用静态工厂方法来实例化.. 36 4.3.2.3 使用实例工厂方法来实例化.. 37 4.4 依赖 38 4.4.1 依赖注入. 38 4.4.1.1 ...

    Spring中文帮助文档

    3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-based)的配置 3.11.1. @Autowired ...

    Spring+3.x企业应用开发实战光盘源码(全)

     第2章:通过一个简单的例子展现开发Spring Web应用的整体过程,通过这个实例,读者可以快速跨入Spring Web应用的世界。  第3章:讲解Spring IoC容器的知识,通过具体的实例详细地讲解IoC概念。同时,对Spring框架...

    Spring.3.x企业应用开发实战(完整版).part2

    10.4.1 Spring通过单实例化Bean简化多线程问题 10.4.2 启动独立线程调用事务方法 10.5 联合军种作战的混乱 10.5.1 Spring事务管理器的应对 10.5.2 Hibernate+Spring JDBC混合框架的事务管理 10.6 特殊方法成漏网之鱼...

    Spring API

    3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10. 以J2EE RAR文件的形式部署Spring ApplicationContext 3.11. 基于注解(Annotation-based)的配置 3.11.1. @Autowired ...

    Spring攻略(第二版 中文高清版).part1

    1.1 实例化Spring IoC容器 1 1.1.1 问题 1 1.1.2 解决方案 1 1.1.3 工作原理 3 1.2 配置Spring IoC容器中的Bean 4 1.2.1 问题 4 1.2.2 解决方案 4 1.2.3 工作原理 4 1.3 调用构造程序创建Bean 14 ...

Global site tag (gtag.js) - Google Analytics