美文网首页
BeanFactory 与 FactoryBean 区别

BeanFactory 与 FactoryBean 区别

作者: 我是昵称鲁班 | 来源:发表于2018-11-15 17:08 被阅读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,可以避免复杂的配置。

  • 传统采用xml配置一个bean的方式,Spring采用反射机制根据<bean>标签中class属性指定实现一个类的实例化并装配成bean。在属性特别多的时候需要编写大量的配置信息,这种场景下配置方式的灵活性受限。

  • 编码方式注册bean能解决上述问题。Spring提供了org.springframwork.bean.factory.FactoryBean接口,用户可以通过该接口定制实例化Bean的逻辑。Spring框架自身就提供了70+FactoryBean的实现。它们隐藏了实例化一些复杂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")。

相关文章

网友评论

      本文标题:BeanFactory 与 FactoryBean 区别

      本文链接:https://www.haomeiwen.com/subject/bfayfqtx.html