`
andyou2012
  • 浏览: 8368 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

BeanFactory与FactoryBean的理解

阅读更多
     BeanFactory很好理解是 IOC 容器的原始基本形式或者说是IOC的核心高级抽象接口形式,用来管理bean的工厂。spring中所有的bean都是用BeanFactory来进行管理的。他的作用包括1.IOC定位xml的位置;2.用来实例化bean(使用getBean()方法)。3.载入xml中bean配置并建立bean之间的依赖关系,贯穿了ioc的初始化bean和 依赖注入(部分)的过程。这里不得不提一下大家熟悉的applicationContext,他包含了beanFactory还扩展了其他很多功能,所以我们一般都用他,而忽视了beanFactory。

    FactoryBean首先他是一个工厂接口类,工厂模式宗旨就是隐藏内部复杂的实现过程,不同于前者他是提供一种专门用来实例化bean的工厂接口类,用于隐藏实例化bean的一系列复杂过程提供给上层调用。主语是bean表明他定义是一种bean,只不过他实现了FactoryBean的接口,通过getObject()来实例化一个bean。
FactoryBean一般情况下,Spring 通过反射机制利用 <bean> 的 class 属性指定实现类实例化 Bean ,在某些情况下,实例化 Bean 过程比较复杂,如果按照传统的方式,则需要在 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个 org.springframework.bean.factory.FactoryBean 的工厂类接口,用户可以通过实现该接口定制实例化 Bean 的逻辑。
FactoryBean接口对于 Spring 框架来说占用重要的地位, Spring 自身就提供了 70 多个 FactoryBean 的实现。它们隐藏了实例化一些复杂 Bean 的细节,给上层应用带来了便利。从 Spring 3.0 开始, FactoryBean 开始支持泛型,即接口声明改为 FactoryBean<T> 的形式:

package org.springframework.beans.factory;  
public interface FactoryBean<T> {  
    T getObject() throws Exception;  
    Class<?> getObjectType();  
    boolean isSingleton();  
}   


在该接口中还定义了以下3 个方法:
T getObject():返回由 FactoryBean 创建的 Bean 实例,如果 isSingleton() 返回 true ,则该实例会放到 Spring 容器中单实例缓存池中;
boolean isSingleton():返回由 FactoryBean 创建的 Bean 实例的作用域是 singleton 还是 prototype ;
Class<T> getObjectType():返回 FactoryBean 创建的 Bean 类型。
当配置文件中<bean> 的 class 属性配置的实现类是 FactoryBean 时,通过 getBean() 方法返回的不是 FactoryBean 本身,而是 FactoryBean#getObject() 方法所返回的对象,相当于 FactoryBean#getObject() 代理了 getBean() 方法。
例:如果使用传统方式配置下面Car 的 <bean> 时, Car 的每个属性分别对应一个 <property> 元素标签。

package  com.baobaotao.factorybean;  
    public   class  Car  {  
        private   int maxSpeed ;  
        private  String brand ;  
        private   double price ;  
        public   int  getMaxSpeed ()   {  
            return   this . maxSpeed ;  
        }  
        public   void  setMaxSpeed ( int  maxSpeed )   {  
            this . maxSpeed  = maxSpeed;  
        }  
        public  String getBrand ()   {  
            return   this . brand ;  
        }  
        public   void  setBrand ( String brand )   {  
            this . brand  = brand;  
        }  
        public   double  getPrice ()   {  
            return   this . price ;  
        }  
        public   void  setPrice ( double  price )   {  
            this . price  = price;  
       }  
} 
 

如果用FactoryBean 的方式实现就灵活点,下例通过逗号分割符的方式一次性的为 Car 的所有属性指定配置值:

package  com.baobaotao.factorybean;  
import  org.springframework.beans.factory.FactoryBean;  
public   class  CarFactoryBean  implements  FactoryBean<Car>  {  
    private  String carInfo ;  
    public  Car getObject ()   throws  Exception  {  
        Car car =  new  Car () ;  
        String []  infos =  carInfo .split ( "," ) ;  
        car.setBrand ( infos [ 0 ]) ;  
        car.setMaxSpeed ( Integer. valueOf ( infos [ 1 ])) ;  
        car.setPrice ( Double. valueOf ( infos [ 2 ])) ;  
        return  car;  
    }  
    public  Class<Car> getObjectType ()   {  
        return  Car. class ;  
    }  
    public   boolean  isSingleton ()   {  
        return   false ;  
    }  
    public  String getCarInfo ()   {  
        return   this . carInfo ;  
    }  
  
    // 接受逗号分割符设置属性信息  
    public   void  setCarInfo ( String carInfo )   {  
        this . carInfo  = carInfo;  
    }  
}   


有了这个CarFactoryBean 后,就可以在配置文件中使用下面这种自定义的配置方式配置 Car Bean 了:
<bean id="car" class="com.baobaotao.factorybean.CarFactoryBean"
    P:carInfo="法拉利 ,400,2000000"/>
当调用getBean("car") 时, Spring 通过反射机制发现 CarFactoryBean 实现了 FactoryBean 的接口,这时 Spring 容器就调用接口方法 CarFactoryBean#getObject() 方法返回。如果希望获取 CarFactoryBean 的实例,则需要在使用 getBean(beanName) 方法时在 beanName 前显示的加上 "&" 前缀:如 getBean("&car");

3、 区别
    BeanFactory是个 Factory ,也就是 IOC 容器或对象工厂, FactoryBean 是个 Bean 。在 Spring 中,所有的 Bean 都是由 BeanFactory( 也就是 IOC 容器 ) 来进行管理的。但对 FactoryBean 而言,这个 Bean 不是简单的 Bean ,而是一个能生产或者修饰对象生成的工厂 Bean, 它的实现与设计模式中的工厂模式和修饰器模式类似。
     

分享到:
评论

相关推荐

    FactoryBean代码最简实现

    这篇代码主要适用于我的博客,用来帮助理解Spring配置文件+FactoryBean的实例化过程。注意,这里是FactoryBean,而不是BeanFactory,下载资源要看清楚哈。

    Spring5.0介绍.pptx

    在学习了书籍Spring5.0后,将自己的理解总结成了ppt,主要包含了IoC 和 DI,AOP,BeanFactory和FactoryBean,事务管理四个方面

    高级开发spring面试题和答案.pdf

    BeanFactory和FactoryBean有什么区别; Spring中用到的设计模式; SPI 机制(Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制), 很多地方有用到: AOP Spring的AOP的底层实现原理; ...

    动力节点SSM课件源码分析教程配套资料分享

    其中有大量一线大厂高频面试问题深度剖析,如MyBatis的Mapper接口底层原理,什么是FactoryBean,什么是BeanFactory?什么是BeanPostProcessor,什么是BeanFactoryPostProcessor?Service中注入的Mapper接口是什么...

    掌握Spring设计模式:Java工程师必备指南

    例如,简单工厂模式通过BeanFactory展现,实现了松耦合和动态对象创建。工厂方法模式则通过FactoryBean接口展示,让对象创建更加灵活。单例模式保证了Bean实例的唯一性,而适配器模式和装饰器模式则提高了代码的可...

    java-advance:java进阶,包含 常用设计模式、线程和并发、spring核心代码、mybatis核心代码、springboot2.0、springcloud G版本、docker的使用、各类面试题

    java进阶源码分析专题常用设计模式线程与并发锁的使用深度理解synchronized、volatile、cas手写ASQSpring5IOC容器设计原理及高级特性AOP设计原理FactoryBean与BeanFactorySpring事务处理机制Spring JDK动态代理...

    Spring面试题

    BeanFactory 使用控制反转 (IOC)模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。 ☆ Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如...

    Spring.3.x企业应用开发实战(完整版).part2

    4.9 FactoryBean 4.10 基于注解的配置 4.10.1 使用注解定义Bean 4.10.2 使用注解配置信息启动Spring容器 4.10.3 自动装配Bean 4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean...

    Spring3.x企业应用开发实战(完整版) part1

    4.9 FactoryBean 4.10 基于注解的配置 4.10.1 使用注解定义Bean 4.10.2 使用注解配置信息启动Spring容器 4.10.3 自动装配Bean 4.10.4 Bean作用范围及生命过程方法 4.11 基于Java类的配置 4.11.1 使用Java类提供Bean...

    Spring中文帮助文档

    3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 3.8.3. 事件 3.8.4. 底层资源的访问 3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10....

    Spring API

    3.8.1. BeanFactory 还是 ApplicationContext? 3.8.2. 利用MessageSource实现国际化 3.8.3. 事件 3.8.4. 底层资源的访问 3.8.5. ApplicationContext在WEB应用中的实例化 3.9. 粘合代码和可怕的singleton 3.10....

Global site tag (gtag.js) - Google Analytics