zoukankan      html  css  js  c++  java
  • 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整合的框架中应用比较多。

  • 相关阅读:
    Java Spring Boot VS .NetCore (十) Java Interceptor vs .NetCore Interceptor
    Java Spring Boot VS .NetCore (九) Spring Security vs .NetCore Security
    IdentityServer4 And AspNetCore.Identity Get AccessToken 问题
    Java Spring Boot VS .NetCore (八) Java 注解 vs .NetCore Attribute
    Java Spring Boot VS .NetCore (七) 配置文件
    Java Spring Boot VS .NetCore (六) UI thymeleaf vs cshtml
    Java Spring Boot VS .NetCore (五)MyBatis vs EFCore
    Java Spring Boot VS .NetCore (四)数据库操作 Spring Data JPA vs EFCore
    Java Spring Boot VS .NetCore (三)Ioc容器处理
    Java Spring Boot VS .NetCore (二)实现一个过滤器Filter
  • 原文地址:https://www.cnblogs.com/warrior4236/p/13229412.html
Copyright © 2011-2022 走看看