zoukankan      html  css  js  c++  java
  • Spring源码分析(十二)FactoryBean的使用

    摘要:本文结合《Spring源码深度解析》来分析Spring 5.0.6版本的源代码。若有描述错误之处,欢迎指正。

    一般情况下,Spring通过反射机制利用bean的class属性指定实现类来实例化bean。在某些情况下,实例化bean过程比较复杂,如果按照传统的方式,则需要在<bean>中提供大量 的配置信息,配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。 Spring 为此提供了一个org.springframework.beans.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化bean的逻辑。

    FactoryBean接口对于Spring框架来说占有重要的地位,Spring自身就提供了70多个 FactoryBean的实现。它们隐藏了实例化一些复杂bean的细节,给上层应用带来了便利。从Spring 3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean<T>的形式:

    public interface FactoryBean<T> {
    
        @Nullable
        T getObject() throws Exception;
    
        @Nullable
        Class<?> getObjectType();
    
        default boolean isSingleton() {
            return true;
        }
    }

    在该接口中还定义了以下3个方法:

    T getObject() 返回由 FactoryBean 创建的 bean 实例,如果 isSingleton()返回 true,则该实例会放到Spring容器中单实例缓存池中
    Class<?> getObjectType() 返回 FactoryBean 创建的 bean 类型
    boolean isSingleton() 返回由FactoryBean创建的bean实例的作用域是singleton还是 prototype。

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

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

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

    public class CarFactoryBean implements FactoryBean<Car> {
    
        private String carInfo;
    
        @Nullable
        @Override
        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;
        }
    
        @Nullable
        @Override
        public Class<?> getObjectType() {
            return Car.class;
        }
    
        @Override
        public boolean isSingleton() {
            return false;
        }
    
        // 接受逗号分隔符设置属性信息
        public void setCarInfo(String carInfo) {
            this.carInfo = carInfo;
        }
    }

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

    <bean id="car" class="org.cellphone.uc.CarFactoryBean" carInfo="超级跑车,400,2000000"/>

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

  • 相关阅读:
    UIVIew详解
    UIView对象转成UIImage对象
    OC 获取IOS屏幕尺寸大小
    presentModalViewController和dismissModalViewControllerAnimated的替代方法
    设计模式之观察者模式(关于OC中的KVO(Observer)KVCNSNotification)
    Key-Value Observing机制
    iOS对象序列化与反序列化( NScoder 和 NScoding )
    IOS 关键字self,super,copy, retain, assign , readonly , readwrite, nonatomic、@synthesize、@property、@dynamic
    UIImage 缩放
    CentOS6.8下二进制安装mysql5.7
  • 原文地址:https://www.cnblogs.com/warehouse/p/9381756.html
Copyright © 2011-2022 走看看