spring源码分析——BeanFactory与FactoryBean的区别

Posted 格物致知

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring源码分析——BeanFactory与FactoryBean的区别相关的知识,希望对你有一定的参考价值。

 

  BeanFactory是spring容器的顶层bean工厂,它提供了从容器获取bean,判断是否存在bean的一些简单方法。FactoryBean是创建

Bean对象的一种方式,如果我们不希望通过扫描注册,就可以使用这种方式注册Bean。

一:BeanFactory接口

 这个接口类提供getBean,containsBean,isSingleton,isPrototype等简单的操作

public interface BeanFactory {

	 
	String FACTORY_BEAN_PREFIX = "&";


	Object getBean(String name) throws BeansException;

	 
	<T> T getBean(String name, Class<T> requiredType) throws BeansException;

	 
	Object getBean(String name, Object... args) throws BeansException;

	 
	<T> T getBean(Class<T> requiredType) throws BeansException;

	 
	<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
 
	<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

	 
	<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

	 
	boolean containsBean(String name);

	 
	boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

	 
	boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

	 
	boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

	 
	boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

	
	@Nullable
	Class<?> getType(String name) throws NoSuchBeanDefinitionException;

	 
	String[] getAliases(String name);

}  

 

我们spring容器拉起的过程中,使用它的子类比较多,

快捷键Ctrl + alt + u 可以查询类的继承关系

 

 

而ApplicationContext与BeanFactory的关系,就是ApplicatationContext在BeanFactroy提供功能的基础上做了一些扩展,比如国际化的操作,解析等

 

 

写个测试类,测试一下拿到的beanFactory对象:

@Component
public class BeanFactoryTest implements BeanFactoryAware {

	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
		System.out.println("beanFactory: "+beanFactory);
		System.out.println("student: "+beanFactory.getBean("student"));
	}

}

  

 

 实际注入的是DefaultListableBeanFactory这个工厂对象,通过这个工厂容器可以拿到bean对象。

 

二:FactoryBean接口

实现FactoryBean接口,这个接口内有三个方法,getObject,实际创建的对象,getObjectType对象类型,isSingleton是否单例

@Component
public class MyFactoryBean implements FactoryBean<User> {

	public User getObject() throws Exception {
		return new User();
	}

	public Class<?> getObjectType() {
		return User.class;
	}

	public boolean isSingleton() {
		return true;
	}
}

  

测试代码:

 

通过运行结果可以看出,beanName为myFactoryBean时,实际返回的是getObject方法的对象,如果想要获取MyFactoryBean本身的对象,需要加上&符号 

 

 

下面我们来分析一下源码怎么实现的?

先来看一下预实例化的时候,判断是否是FactoryBean,

 

 

 

 

 

 判断是否是FactoryBean接口的实例,很显然,MyFactoryBean是的,然后调用getBean实例化这个对象,beanName前面加上&,就是实例化自身的对象

 

 

实例化完成后

 

 

 

 直接返回这个实例对象,只有是FactoryBean对象,同时没有&符合时,才会去调用getObject方法,

 

看一下没有&符号的getBean:

 

因为已经预实例化,所以缓存中存在MyFactoryBean这个对象,走到getObjectForBeanInstance这个方法

 

 

 

 

 

 

 

调用getObject方法获取真实的对象,这样实际上返回的是User对象。

 

 

如果前面加上&符号时,返回的是本身的对象,我们来分析一下

 

 

 

 因为是以&开头的,所以直接返回这个实例对象,而没有去调用getObject方法。

 

 

 

 

 

 以上便是获取FactoryBean本身对象的过程。

 

上面都是单例的情况,如果isSingleton是false呢

 

 

 

 如果是isSingleton为false或者母体类就是非单例,那么直接getObject返回,跟缓存没有关系

 

 以上就是从源码层面分析了FactoryBean的使用以及如何实现,这个接口在mybatis等和spring整合的框架中应用比较多。

 

以上是关于spring源码分析——BeanFactory与FactoryBean的区别的主要内容,如果未能解决你的问题,请参考以下文章

Spring源码分析 ---- BeanFactory接口的设计分析

Spring IOC 源码简单分析 01 - BeanFactory

Spring源码分析(二十三)BeanFactory的后处理

spring源码分析系列5:ApplicationContext的初始化与Bean生命周期

Spring源码解析 - BeanFactory

spring源码分析:spring生命周期二