Spring源码之bean的加载(三)从bean中获取对象

来源:互联网 发布:线割编程招聘 编辑:程序博客网 时间:2024/03/29 15:31

在上一章节中,我们知道了Spring是如何去获取单例bean,而这一章节我们将要去了解Spring是如何从bean获取对象。(相关资源可到这里下载:http://pan.baidu.com/s/1sjSo9a9)


在最开始前面我们知道了,Spring的获取bean的方法的入口函数是getObjectForBeanInstance。那么我们就跟着时序图一步一步赶往代码查看。

1)        首先,我们要看在是getObjectForInstance的函数,这个函数主要做的事情是:

a)        对FactoryBean正确的验证

b)        对非FactoryBean不做任何处理

c)        对bean进行转换

d)        将从Factory中解析bean的工作委托给getObjectFromFactoryBean

 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.//如果指定的name是工厂相关(以&为前缀)且beanInstance又不是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.//现在我们有了bean的实例,这个实例可能会是正常的bean或者是FactoryBean//如果是FactoryBean我们使用它创建实例,但是如果是用户想要获取工厂实例而不是工厂的//getObject方法对应 的实例,那么传入的name应该加入前缀if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {return beanInstance;}       //加载FactoryBeanObject object = null;if (mbd == null) {//尝试从缴存中加载beanobject = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.//到这里已经明确知道beanInstance一定是FactoryBean类型FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.//containsBeanDefinition检测beanDefinitionMap中也就是在所有已经加载的类中检测是否定义beanNameif (mbd == null && containsBeanDefinition(beanName)) {//将存储XML配置文件的GenericBeanDfinition转换为RootBeanDefinition,如果指定BeanName是子Bean的话同时会合并父类的相关属性mbd = getMergedLocalBeanDefinition(beanName);}//是否是用户定义的而不是应用程序本身定义的boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}

2)        我们继续跟踪代码到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;}}

3)        在上面的方法中,我们比较关心的是doGetObjectFromFactoryBean ()的方法,这个方法中有一行代码是:object = factory.getObject(),这似乎是我们想要看到的。

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>() {@Overridepublic Object run() throws Exception {return factory.getObject();}}, acc);}catch (PrivilegedActionException pae) {throw pae.getException();}}else {//直接调用getObject方法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;}

4)        方法中的object = factory.getObject()得到了我们想要的结果,但是并没有直接返回,我们继续到getObjectFromFactoryBean方法的postProcessObjectFromFactoryBean方法下,再进入applyBeanPostprocessorsAfterInitiallization()的方法,就可以得到结果了。

@Overrideprotected Object postProcessObjectFromFactoryBean(Object object, String beanName) {return applyBeanPostProcessorsAfterInitialization(object, beanName);}

@Overridepublic Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {result = beanProcessor.postProcessAfterInitialization(result, beanName);if (result == null) {return result;}}return result;}





0 0
原创粉丝点击