Spring中的beanFactory和FactoryBean

首先,BeanFactoryFactoryBean都是Spring中的接口。

  • BeanFactory顾名思义,是用来管理,配置BeanFactory
  • FactoryBean顾名思义,首先是一个Bean,为什么叫FactoryBean,因为它是由Spring管理的,一个产生BeanBean,调用它真正返回的Bean不是factoryBean的实例,而是返回实现该接口的getObject()中返回的Bean,如果要返回该FactoryBean实例,需要在调用的位置加上&号。

首先看一下接口:

public interface FactoryBean {
    //通过Spring容器获取的Bean实质是getObject()方法返回的对象T
    T getObject() throws Exception;
    //返回类型
    Class getObjectType();
    //是否单例
    boolean isSingleton();
}

举个例子:

  • 首先定义一个Bean:
package com.github.jettyrun.springinterface.demo.bean;

/**
 * Created by jetty on 18/1/31.
 */
public class Car {

    private String name;

    private String color;

    private String weight;

    public void setName(String name) {
        this.name = name;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public void setWeight(String weight) {
        this.weight = weight;
    }
}
  • 实现两种不同的FactoryBean,一种单例(Singleton),一种多例(protoType)
package com.github.jettyrun.springinterface.demo.factorybean;

import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

/**
 * Created by jetty on 18/1/31.
 */

@Component("protoTypeCarFactoryBean")
public class ProtoTypeCarFactoryBean implements FactoryBean{

    public Car getObject() throws Exception {
        return new Car();
    }

    public Class getObjectType() {
        return Car.class;
    }

    public boolean isSingleton() {
        return false;
    }
}
package com.github.jettyrun.springinterface.demo.factorybean;

import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.stereotype.Component;

/**
 * Created by jetty on 18/1/31.
 */
@Component("singletonCarFactoryBean")
public class SingletonCarFactoryBean implements FactoryBean{

    private Car carProxy=new Car();

    public Car getObject() throws Exception {
        return carProxy;
    }

    public Class getObjectType() {
        return null;
    }

    public boolean isSingleton() {
        return true;
    }
}
  • main方法运行测试
package com.github.jettyrun.springinterface.demo.factorybean;

import com.github.jettyrun.springinterface.demo.bean.Car;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Created by jetty on 18/1/31.
 */
public class Main {

    public static void main(String[] args) {
        ApplicationContext beans=new ClassPathXmlApplicationContext("classpath:application-usertag.xml");
        Car protoTypeCar1= (Car)beans.getBean("protoTypeCarFactoryBean");
        Car protoTypeCar2= (Car)beans.getBean("protoTypeCarFactoryBean");
        System.out.println(""+(protoTypeCar1==protoTypeCar2)+" "+protoTypeCar1+" "+protoTypeCar2);
        Car singletonCar1= (Car)beans.getBean("singletonCarFactoryBean");
        Car singletonCar2= (Car)beans.getBean("singletonCarFactoryBean");
        System.out.println(""+(singletonCar1==singletonCar2)+" "+singletonCar1+" "+singletonCar2);

        SingletonCarFactoryBean factoryBean1=(SingletonCarFactoryBean)beans.getBean("&singletonCarFactoryBean");
        SingletonCarFactoryBean factoryBean2=(SingletonCarFactoryBean)beans.getBean("&singletonCarFactoryBean");
        System.out.println(""+(factoryBean1==factoryBean2)+" "+factoryBean1+" "+factoryBean2);

    }
}
  • 运行结果:
false com.github.jettyrun.springinterface.demo.bean.Car@710f4d59 com.github.jettyrun.springinterface.demo.bean.Car@239f480c
true com.github.jettyrun.springinterface.demo.bean.Car@2e331e19 com.github.jettyrun.springinterface.demo.bean.Car@2e331e19
true com.github.jettyrun.springinterface.demo.factorybean.SingletonCarFactoryBean@1dfd1301 com.github.jettyrun.springinterface.demo.factorybean.SingletonCarFactoryBean@1dfd1301

我们能看到,通过Spring容器获取protoTypeCarFactoryBeansingletonCarFactoryBean对象,实质返回的是该对象调用的getObject()方法返回的对象,如果要获取FactoryBean的真正类型,则需要在beanId前加上&符号。

BeanFactory到底又是如何使用的。

我们将上面的main方法做一下改变,将ApplicationContext改为BeanFactory。如下:

public static void main(String[] args){
        Resource resource = new FileSystemResource("src/main/resources/application-usertag.xml");
        BeanFactory factory = new XmlBeanFactory(resource);
        Car protoTypeCar1= (Car)factory.getBean("protoTypeCarFactoryBean");
        Car protoTypeCar2= (Car)factory.getBean("protoTypeCarFactoryBean");
        System.out.println(""+(protoTypeCar1==protoTypeCar2)+" "+protoTypeCar1+" "+protoTypeCar2);
        Car singletonCar1= (Car)factory.getBean("singletonCarFactoryBean");
        Car singletonCar2= (Car)factory.getBean("singletonCarFactoryBean");
        System.out.println(""+(singletonCar1==singletonCar2)+" "+singletonCar1+" "+singletonCar2);

        SingletonCarFactoryBean factoryBean1=(SingletonCarFactoryBean)factory.getBean("&singletonCarFactoryBean");
        SingletonCarFactoryBean factoryBean2=(SingletonCarFactoryBean)factory.getBean("&singletonCarFactoryBean");
        System.out.println(""+(factoryBean1==factoryBean2)+" "+factoryBean1+" "+factoryBean2);
    }

运行结果和上面的运行结果完全一样。
这就表示着在Spring中,所有的bean都是被beanFactory管理,需要获取bean的时候,实质是去beanFactory中获取。applicationContext本身是实现BeanFactory接口的实现。
如下:

public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver {

HierarchicalBeanFactory本身是继承BeanFactory接口的。
也就是上面所说的,FactoryBean是一个为了产生BeanBean,而BeanFactory是用来管理,产生Bean的一个Factory
代码地址:https://gitee.com/shxz130/SpringInterfaceDemo/

你可能感兴趣的:(Spring中的beanFactory和FactoryBean)