标签:技术 没有 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