码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2020-07-03 12:35:51      阅读:65      评论:0      收藏:0      [点我收藏+]

标签:技术   没有   rgs   mamicode   contains   image   过程   nfa   开头   

 

  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的区别

标签:技术   没有   rgs   mamicode   contains   image   过程   nfa   开头   

原文地址:https://www.cnblogs.com/warrior4236/p/13229412.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!