创建Bean的方式

本文介绍了Spring框架中创建Bean的三种方式:构造器创建、静态工厂方法创建和实例工厂方法创建。详细展示了每种方式的配置过程及其实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring主要支持如下的三种方式来创建Bean。

1)        调用构造器创建Bean.

2)        调用静态工厂方法创建Bean

3)        调用实例工厂方法创建Bean

1.使用构造器创建Bean实例

如果采用构造注入,则要求配置文件为<bean…/>元素添加<constructor…/>子元素,每个<constructor…/>子元素配置一个构造器参数。Spring容器将使用带对应参数的构造器来创建Bean实例,Spring调用构造器传入的参数即可用于初始化Bean的实例,最后也将一个完整的Bean实例返回给程序。

2.使用静态工厂方法创建Bean

使用静态工厂方法创建Bean实例时,class属性也必须指定,但此时class属性不是指定Bean实例的实现类,而静态工厂类,Spring通过该属性知道由哪个工厂类创建Bean实例。<bean…./>元素需要指定如下两个属性:

1)        class:该属性的值为静态工厂方法来生产Bean实例

2)        factory-method:该属性指定静态工厂方法来生产Bean实例

下面定义一个Being接口,静态工厂方法所生产的产品是该接口的实例。

 public interface Being
{
	public void testBeing();
}

下面定义接口的两个实现类,静态工厂方法将会产生这两个实现类的实例。

Ø  Cat.java

 public class Cat implements Being
{
	private String msg;
	// msg的setter方法
	public void setMsg(String msg)
	{
		this.msg = msg;
	}
	// 实现接口必须实现的testBeing方法
	public void testBeing()
	{
		System.out.println(msg +
			",猫喜欢吃老鼠");
	}
}

Ø  Dog.java

 public class Dog implements Being
{
	private String msg;
	// msg的setter方法
	public void setMsg(String msg)
	{
		this.msg = msg;
	}
	// 实现接口必须实现的testBeing()方法
	public void testBeing()
	{
		System.out.println(msg +
			",狗爱啃骨头");
	}
}

 下面的BeingFactory工厂包含了一个getBeing()静态方法,该静态方法用于返回一个Being实例,这就是典型的静态工厂。

 public class BeingFactory
{
	// 返回Being实例的静态工厂方法
	// arg参数决定返回哪个Being类的实例
	public static Being getBeing(String arg)
	{
		// 调用此静态方法的参数为dog,则返回Dog实例
		if (arg.equalsIgnoreCase("dog"))
		{
			return new Dog();
		}
		// 否则返回Cat实例
		else
		{
			return new Cat();
		}
	}
}

指定Spring让BeingFactory来生产Being对象,则应该按如下静态工厂方法的方式来配置Dog、Cat Bean。Spring配置文件如下。

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<!-- 下面配置驱动Spring调用BeingFactory的静态getBeing()方法来创建Bean
	该bean元素包含的constructor-arg元素用于为静态工厂方法指定参数,
	因此这段配置会驱动Spring以反射方式来执行如下代码:
	dog = com.owen.app.factory.BeingFactory.getBeing("dog"); -->
	<bean id="dog" class="com.owen.app.factory.BeingFactory"
		factory-method="getBeing">
		<!-- 配置静态工厂方法的参数 -->
		<constructor-arg value="dog"/>
		<!-- 驱动Spring以"我是狗"为参数来执行dog的setMsg()方法 -->
		<property name="msg" value="我是狗"/>
	</bean>
	<!--  下面配置会驱动Spring以反射方式来执行如下代码:
	dog = com.owen.app.factory.BeingFactory.getBeing("cat"); -->
	<bean id="cat" class="com.owen.app.factory.BeingFactory"
		factory-method="getBeing">
		<!-- 配置静态工厂方法的参数 -->
		<constructor-arg value="cat"/>
		<!-- 驱动Spring以"我是猫"为参数来执行dog的setMsg()方法 -->
		<property name="msg" value="我是猫"/>
	</bean>
</beans>

下面定个SpringTest.java用来测试。

public class SpringTest
{
	public static void main(String[] args)
	{
		// 以类加载路径下的配置文件创建ClassPathResource实例
		ApplicationContext ctx = new
			ClassPathXmlApplicationContext("beans.xml");
		Being b1 = ctx.getBean("dog" , Being.class);
		b1.testBeing();
		Being b2 = ctx.getBean("cat" , Being.class);
		b2.testBeing();
	}
}

通过静态工厂创建实例时需要对配置文件进行如下改变:

1)        class属性的值不再是Bean实例的实现类,而是生成Bean实例的静态工厂类。

2)        使用factory-method属性指定创建Bean实例的静态工厂方法

3)        如果静态工厂方法需要参数,则使用<constructor-arg…/>元素指定静态工厂方法的参数。

3.调用实例工厂方法创建Bean

使用实例工厂方法时,配置Bean实例的<bean../>元素无须class属性,因为Spring容器不再直接实例化该Bean,Spring容器仅仅调用实例工厂的工厂方法,工厂方法负责创建Bean实例。采用实例工厂方法创建Bean的<bean…/>元素时需要指定如下两个属性:

1)        factory-bean:该属性的值为工厂Bean的id

2)        factory-method:该属性指定实例工厂的工厂方法

下面先定义一个Person接口,实例工厂方法所产生的对象将实例Person接口。

public interface Person
{
	// 定义一个打招呼的方法
	public String sayHello(String name);
	// 定义一个告别的方法
	public String sayGoodBye(String name);
}

下面是Person的第一个接口类:American.

public class American implements Person
{
	// 实现Person接口必须实现如下两个方法
	public String sayHello(String name)
	{
		return name + ",Hello!";
	}
	public String sayGoodBye(String name)
	{
		return name + ",Good Bye!";
	}
}

  下面是Person的第二个接口类Chinese

public class Chinese implements Person
{
	// 实现Person接口必须实现如下两个方法
	public String sayHello(String name)
	{
		return name + ",您好";
	}
	public String sayGoodBye(String name)
	{
		return name + ",下次再见";
	}
}
下面定义个PersonFactory为Person的工厂类。
 public class PersonFactory
{
	// 获得Person实例的实例工厂方法
	// ethnic参数决定返回哪个Person实现类的实例
	public Person getPerson(String ethnic)
	{
		if (ethnic.equalsIgnoreCase("chin"))
		{
			return new Chinese();
		}
		else
		{
			return new American();
		}
	}
}

  下面配置Spring的配置文件 bean.xml

<?xml version="1.0" encoding="GBK"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">
	<!-- 配置工厂Bean,该Bean负责产生其他Bean实例 -->
	<bean id="personFactory" class="com.owen.app.factory.PersonFactory"/>
	<!-- 下面配置驱动Spring调用personFactory Bean的getPerson()方法来创建Bean
	该bean元素包含的constructor-arg元素用于为工厂方法指定参数,
	因此这段配置会驱动Spring以反射方式来执行如下代码:
	PersonFactory pf = container.get("personFactory"); // container代表Spring容器
	chinese = pf.getPerson("chin"); -->
	<bean id="chinese" factory-bean="personFactory" 
		factory-method="getPerson">
		<!-- 配置实例工厂方法的参数 -->
		<constructor-arg value="chin"/>
	</bean>
	<!--  下面配置会驱动Spring以反射方式来执行如下代码:
	PersonFactory pf = container.get("personFactory"); // container代表Spring容器
	american = pf.getPerson("ame"); -->
	<bean id="american" factory-bean="personFactory"
		factory-method="getPerson">
		<constructor-arg value="ame"/>
	</bean>
</beans>

  下面写一个Test的类,用于测试。

public class SpringTest
{
	public static void main(String[] args)
	{
		ApplicationContext ctx = new
			ClassPathXmlApplicationContext("beans.xml");
		Person p1 = ctx.getBean("chinese"
			, Person.class);
		System.out.println(p1.sayHello("Mary"));
		System.out.println(p1.sayGoodBye("Mary"));
		Person p2 = ctx.getBean("american"
			, Person.class);
		System.out.println(p2.sayHello("Jack"));
		System.out.println(p2.sayGoodBye("Jack"));
	}
}

4. 总结

调用实例工厂方法创建Bean,与调用静态工厂方法创建Bean的用法基本相似。区别如下 :

1)        配置实例工厂方法创建Bean,必须将实例工厂配置成Bean实例;而配置静态工厂方法创建Bean,则无须配置工厂Bean。

2)        配置实例工厂方法创建Bean,必须使用factory-bean属性确定工厂Bean;而配置静态工厂方法创建Bean,则使用class元素确定静态工厂类。

实例工厂方法创建与静态方法创建的相同地方如下:

1)        者需要使用factory-method属性指定生产Bean实例的工厂方法。

2)        工厂方法如果需要参数,都使用<constructor../>元素指定参数值

3)        普通的设置注入,都使用<property../>元素确定参数值









   



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值