栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

源码分析FactoryBean 接口的核心功能

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

源码分析FactoryBean 接口的核心功能

源码分析FactoryBean 接口的核心功能是今天的主要内容,下面我们通用一个测试类为入口来详细其核心源码:

1、测试类:

import com.enjoy.jack.bean.Student;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;


@Component
public class FactoryBeanDemo implements FactoryBean {
    @Override
    public Object getObject() throws Exception {
        return new Student();
    }

    @Override
    public Class getObjectType() {
        return Student.class;
    }
}

实体:

@Data
public class Student {
    private String username = "nandao";
}

 

2、核心配置:spring.xml



  

    
    

   
   

 

3、运行测试:

 @Test
    public void test20() {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        Student student = (Student)applicationContext.getBean("factoryBeanDemo");
        System.out.println(student);

        FactoryBeanDemo factoryBeanDemo = (FactoryBeanDemo)applicationContext.getBean("&factoryBeanDemo");
        System.out.println(factoryBeanDemo);
    }

4、结果:

发现没有“&”号为什么根据Id获取到的是getObject方法的返回对象,下面看看源码 

 5、源码入口:AbstractBeanFactory 类的doGetBean 接口

        //从缓存中拿实例
		// Eagerly check singleton cache for manually registered singletons.
		Object sharedInstance = getSingleton(beanName);
		//如果缓存里面能拿到实例
		if (sharedInstance != null && args == null) {
			if (logger.isTraceEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
							"' that is not fully initialized yet - a consequence of a circular reference");
				}
				else {
					logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
				}
			}
			//该方法是FactoryBean接口的调用入口
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

点击 getObjectForBeanInstance(sharedInstance, name, beanName, null);接口

protected Object getObjectForBeanInstance(
			Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

		// Don't let calling code try to dereference the factory if the bean isn't a factory.
        //判断对象前面是否家里“&” 符号,如果加了,可能直接返回当前实例的对象;如果没加继续往下走,最终返回getObject里面的对象。
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if (!(beanInstance instanceof FactoryBean)) {
				throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
			}
			if (mbd != null) {
				mbd.isFactoryBean = true;
			}
			return beanInstance;
		}

		// 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.
		//如果实例不是FactoryBean类型的
		if (!(beanInstance instanceof FactoryBean)) {
			return beanInstance;
		}

		//如果代码能走下来,则说明 beanName不是以&开头,并且beanInstance是FactoryBean类型的
		Object object = null;
		if (mbd != null) {
			mbd.isFactoryBean = true;
		}
		else {
			//从缓存里面拿FactoryBean类型的实例
			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());
			//重点看,里面是调用getObject方法,获取对象信息
			object = getObjectFromFactoryBean(factory, beanName, !synthetic);
		}
		return object;
	}

6、点击 BeanFactoryUtils.isFactoryDereference(name)

	public static boolean isFactoryDereference(@Nullable String name) {
        //判断name里面首个字符串是不是“&”,如果是直接返回true
        //	String FACTORY_BEAN_PREFIX = "&";
		return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
	}

这里就判断了id中有没有存在“&”符号,如果有则返回true,返回true就直接return beanInstance;把实例本身返回了,而实例本身就是例子中的FactoryBeanDemo 

7、点击 getObjectFromFactoryBean(factory, beanName, !synthetic);进入父类FactoryBeanRegistrySupport

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) {
					//调用getObject方法,点击进入
					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 (shouldPostProcess) {
							if (isSingletonCurrentlyInCreation(beanName)) {
								// Temporarily return non-post-processed object, not storing it yet..
								return object;
							}
							beforeSingletonCreation(beanName);
							try {
								object = postProcessObjectFromFactoryBean(object, beanName);
							}
							catch (Throwable ex) {
								throw new BeanCreationException(beanName,
										"Post-processing of FactoryBean's singleton object failed", ex);
							}
							finally {
								afterSingletonCreation(beanName);
							}
						}
						if (containsSingleton(beanName)) {
							//把实例缓存到factoryBeanObjectCache map中,这个是单独缓存FactoryBean类型实例的map
							this.factoryBeanObjectCache.put(beanName, object);
						}
					}
				}
				return object;
			}
		}
		else {
			Object object = doGetObjectFromFactoryBean(factory, beanName);
			if (shouldPostProcess) {
				try {
					object = postProcessObjectFromFactoryBean(object, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
				}
			}
			return object;
		}
	}

点击 doGetObjectFromFactoryBean(factory, beanName);方法

private Object doGetObjectFromFactoryBean(FactoryBean factory, String beanName) throws BeanCreationException {
		Object object;
		try {
			if (System.getSecurityManager() != null) {
				AccessControlContext acc = getAccessControlContext();
				try {
					object = AccessController.doPrivileged((PrivilegedExceptionAction) 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) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(
						beanName, "FactoryBean which is currently in creation returned null from getObject");
			}
			object = new NullBean();
		}
		return object;
	}
 

 8、此处  factory.getObject(); 就是调到了业务方法,如下:

这里就调到了getObject方法,所以拿到的对象就是getObject方法返回的对象。

总之,从分析源码我们可以看到,就是一个“&”符号控制了代码的流转,有“&”拿到的是类本身实例,没有“&”拿到的getObject返回实例,到此FactoryBean分析完毕。 

转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号