BeanFactory 与 FactoryBean 区别

2018-11-15  本文已影响13人  我是昵称鲁班

BeanFacory

字面理解:以Factory结尾,是一个工厂接口,用于管理bean工厂。

作用
1)实例化 (Instance)
2)定位 (缓存Map beanId->Instance)
3)建立bean之间的依赖关系

Resource resource = new FileSystemResource("spring.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
ClassPathResource resource = new ClassPathResource ("spring.xml");
BeanFactory beanFactory(resource);
Application context = new ClassPathXmlApplicationContext(new String[]{"partOne.xml","paryTwo.xml"});
BeanFactory beanFactory =context;

如果是采用微服务框架,获取ApplicaitonContext的方式可以采用下面这种:

public ApplicationContextHelper implements  ApplicationContextAware{
@Override

}

拿到beanFactory,接着使用getBean(String beanName)方法就可以取得bean的实例;

BeanFactory方法
1 boolean containsBean(String beanName)
判断工厂中是否包含给定名称的bean定义,若有则返回true
2 Object getBean(String)
返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常。
3 Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型。
4 Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则排除NoSuchBeanDefinitionException异常。
5 boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式。
6 String[] getAliases(String name) 返回给定bean名称的所有别名。

FactoryBean

字面意思:以Bean为结尾,是一个Bean。不同于普通Bean该bean可以生产Bean。

作用:通过编码的方式配置bean,可以避免复杂的配置。

接口定义:

public interface FactoryBean<T> {

   @Nullable
   T getObject() throws Exception;//返回由FactoryBean创建的bean实例,如果isSingleton()返回true,则该实例会放到Spring容器中单实例缓存池中。

   @Nullable
   Class<?> getObjectType();//返回FactoryBean创建的bean类型。

   default boolean isSingleton() {
       return true;
   }//返回由FactoryBean创建的bean实例的作用域是singleton还是prototype。
}

具体实例:

当配置文件中<bean>的class属性配置的实现类是FactoryBean时,通过 getBean()方法返回的不是FactoryBean本身,而是FactoryBean#getObject()方法所返回的对象,相当于FactoryBean#getObject()代理了getBean()方法。例如:如果使用传统方式配置下面Car的<bean>时,Car的每个属性分别对应一个<property>元素标签。

public   class  Car  {    
       private   int maxSpeed ;    
       private  String brand ;    
       private   double price ;    
      //  get/set方法l略  
}

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

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 . carInfocarInfo  = carInfo;    
    }    
}     

有了这个CarFactoryBean后,就可以在配置文件中使用下面这种自定义的配置方式配置Car Bean了:

<bean id="car" class="com.test.factorybean.CarFactoryBean" carInfo="超级跑车,400,2000000"/> 

当调用getBean("car") 时,Spring通过反射机制发现CarFactoryBean实现了FactoryBean的接口,这时Spring容器就调用接口方法CarFactoryBean#getObject()方法返回。如果希望获取CarFactoryBean的实例,则需要在使用getBean(beanName) 方法时在beanName前显示的加上 "&" 前缀,例如getBean("&car")。

上一篇 下一篇

猜你喜欢

热点阅读