欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring FactoryBean理解 博客分类: Spring4.X  

程序员文章站 2024-02-12 19:29:40
...
这是开通这个ID后写的第一篇文章,所以絮叨下。最近在看Spring4.X的内容,期间遇到许多问题,还好相继都解决了。原本想把这些问题都记录到博客上,只是苦于生活中的责任,未能抽出时间完成,其实这也是给自己找理由,以后还是尽力多写写博文,也算是对自己的一种交代。不废话了,开干吧。

首先搞清楚BeanFactory和FactoryBean的区别:因为这俩长得有点像,所以说拉出来一起看看。

BeanFactory是一个类工厂,也叫SpringIOC容器,就是用来管理Bean的,也就是管理Java对象。它是Spring的基础设施,面向Spring本身,与之对应的有个Spring容器,较ApplicationContext,这个是面向Spring框架的开发者的,比BeanFactory要高级点,谁让BeanFactory是底层的呢。

而FactoryBean是一个工厂类接口,我们可以通过实现这个接口来定制实例化Bean的逻辑,意思就是说实现了这个接口,你就可以用它里面的方法来定制化如何实例化Bean.

简单点就是一个是容器,管理Bean的;另一个就是个接口,用来定制实例化Bean的。

下面说说FactoryBean。

从Spring3.0开始,它支持泛型了,就是接口声明变成了FactoryBean<T>。实现了它的类肯定必须实现它的方法,有3个:
T getObject(); 返回FactoryBean创建的Bean实例,注意它的返回类型是T,不是FactoryBean。

boolean isSingleton(); 确定Bean的作用域的,singleton还是prototype。
说说这两种作用域的区别:
一个是单实例的,实例化的Bean会放到SpringIOC容器的缓存池中,将Bean的引用返回给调用者,Spring继续对其进行生命周期管理;而prototype则是将Bean返回给调用者,然后Spring就不管了,由调用者对Bean进行后续生命周期管理。Spring将Bean的作用域默认为singleton.

Class<?>getObjectType()。返回FactoryBean创建Bean的类型。

重点说说使用的时候,主要是这个getBean()。

假设这样定义
<bean id="car" class="com.smart.fb.CarFactoryBean"
        p:carInfo="梅赛德斯奔驰GLE,300,8888888.88" />
当然com.smart.fb.CarFactoryBean肯定是实现了FactoryBean<T>接口的。

当调用getBean("car")的时候,返回的是CarFactoryBean的getObject()返回的工厂类创建的对象T,而不是CarFactoryBean。如果想要得到CarFactoryBean,则需要使用getBean("&car").

代码1:

public class CarFBTest {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/fb/beans.xml");
        CarFactoryBean carfb = ctx.getBean("&car", CarFactoryBean.class);

        System.out.println(carfb.getObject().toString());
        System.out.println(carfb.getObjectType().toString());
        System.out.println(carfb.isSingleton());
    }
}

结果1:
Car{maxSpeed=300, brand='梅赛德斯奔驰GLE', price=8888888.88}
class com.smart.fb.Car
false

******************************************

代码2:
public class CarFBTest {
    public static void main(String[] args) throws Exception {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("com/smart/fb/beans.xml");
        Car car = ctx.getBean("car", Car.class);

        System.out.println(car.toString());
        System.out.println(car.getClass());
    }
}

结果2:
Car{maxSpeed=300, brand='梅赛德斯奔驰GLE', price=8888888.88}
class com.smart.fb.Car