7.8.4: 容器中的 工厂Bean

此处的工厂Bean,与前面介绍的实例工厂方法创建Bean,或者静态工厂方法创建Bean的工厂有所区别:前面那些工厂是标准的工厂模式,Spring只是负责调用工厂方法来创建Bean实例;此处的 工厂Bean 是Spring的一种特殊Bean,这种工厂Bean必须实现FactoryBean接口

FactoryBean接口是工厂Bean的标准接口,实现该接口的Bean通常只能作为工厂Bean使用,当我们将工厂Bean部署在容器中,并通过getBean( )方法来获取工厂Bean时,容器不会返回FactoryBean实例,而是返回FactoryBean的产品。

FactoryBean接口提供如下三个方法:

Object getObject( ) 实现该方法负责返回该工厂Bean生成的Java实例。
Class getObjectType( ) 实现该方法返回该工厂Bean生成的Java实例的实现类。
boolean isSingleton( ) 实现该方法表示该工厂Bean生成的Java实例是否为单例模式。
实现FactoryBean接口的Bean无法作为正常Bean使用,配置FactoryBean与配置普通Bean没有区别,但当客户端对该Bean id请求时,容器返回该FactoryBean的产品,而不是返回该FactoryBean本身。

7.8.4: 容器中的 工厂Bean_第1张图片

Person.java :

public interface Person {
	
	public String sayHello(String name);
	public String sayGoodBye(String name);
}
Chinese.java :

public class Chinese implements Person{

	@Override
	public String sayGoodBye(String name) {
		return "再见,"+name;
	}

	@Override
	public String sayHello(String name) {
		return "你好,"+name;
	}

	
}
PersonFactory.java :

public class PersonFactory implements FactoryBean {

	private Person p;
	
        //返回工厂Bean所生产的产品
	public Person getObject(){
		if(p==null){
			p=new Chinese();
		}
		return p;
	}

        //获取工厂Bean所生产的产品的类型
	public Class<?> getObjectType() {
		return Chinese.class;
	}

        //返回该工厂Bean所生产的产品是否为单例
	public boolean isSingleton() {
		return true;
	}

}
bean.xml核心配置:

<bean id="chinese" class="com.bean.PersonFactory"/>
Test.java :

public class Test {

	public static void main(String[] args) {
		
		ApplicationContext ctx=new ClassPathXmlApplicationContext("bean.xml");
		//直接请求FactoryBean时,系统将返回该FactoryBean的产品
		Person p1=(Person) ctx.getBean("chinese");//1
		System.out.println(p1.sayHello("汤姆"));
		System.out.println(p1.sayGoodBye("汤姆"));
		//再次获取该FactoryBean的产品
		Person p2=(Person) ctx.getBean("chinese");//2
		System.out.println(p1==p2);
		System.out.println(ctx.getBean("&chinese"));//3
	}

}
运行Test.java,控制台输出:


上面的PersonFactory是一个标准的工厂Bean,该PersonFactory的getObject( )方法保证每次产生的Person对象是单例的,故该工厂类的isSingleton( )方法返回true。

Test.java中1和2直接请求容器中的FactoryBean,Spring将不会返回该FactoryBean实例,而是返回该FactoryBean的产品;程序3在Bean id前增加&符号,这将会让Spring返回FactoryBean本身。

因为FactoryBean以单例方式管理产品Bean,因此两次请求的产品,是同一个共享实例。

当程序需要获取FactoryBean本身时,并不直接请求Bean id,而是在Bean id前增加&符号。

对于初学者而言,可能无法体会到 工厂Bean 的作用。实际上,FactoryBean是Spring中非常有用的一个接口,Spring内置提供了很多实用的工厂Bean,例如TransactionProxyFactoryBean等,这个工厂Bean专门用于为目标Bean创建事务代理。

Spring提供的工厂Bean,大多以FactoryBean后缀结尾,Spring提供的工厂Bean,大多用于生产一批具有某种特征的Bean实例,工厂Bean是Spring的一个重要工具类。



你可能感兴趣的:(FactoryBean)