Spring-6.创建bean的三种方式

Spring支持使用三种方式创建bean

(1)调用构造器创建bean

(2)静态工厂方法

(3)实例工厂方法

一、构造器创建

给定class属性,bean提供无参构造器(或构造器注入时有参),以反射创建。(之前已有大量例子)

二、静态工厂创建bean(无需创建工厂类实例,工厂方法必须是静态的)

指定以下属性:

(1)class

(2)factory-method

接口:

package codeEETest;
public interface Being
{
	public void testBeing();
}
实现类1:

package codeEETest;

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 +
			",狗爱啃骨头");
	}
}

实现类2:

package codeEETest;

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 +
			",猫喜欢吃老鼠");
	}
}
xml:(以静态工厂方式配置的,一个bean中完成)

<!-- 下面配置驱动Spring调用BeingFactory的静态getBeing()方法来创建Bean
	该bean元素包含的constructor-arg元素用于为静态工厂方法指定参数,
	因此这段配置会驱动Spring以反射方式来执行如下代码:
	dog = org.crazyit.app.factory.BeingFactory.getBeing("dog"); 
	-->
	
	<bean id="dog" class="codeEETest.BeingFactory"
		factory-method="getBeing">
		<!-- 配置静态工厂方法的参数 -->
		<constructor-arg value="dog"/>
		<!-- 驱动Spring以"我是狗"为参数来执行dog的setMsg()方法 -->
		<property name="msg" value="我是狗"/>
	</bean>
	
	<!--  下面配置会驱动Spring以反射方式来执行如下代码:
	dog = org.crazyit.app.factory.BeingFactory.getBeing("cat"); 
	-->

	<bean id="cat" class="codeEETest.BeingFactory"
		factory-method="getBeing">
		<!-- 配置静态工厂方法的参数 -->
		<constructor-arg value="cat"/>
		<!-- 驱动Spring以"我是猫"为参数来执行dog的setMsg()方法 -->
		<property name="msg" value="我是猫"/>
	</bean>

测试:

package codeEETest;

import org.springframework.context.*;
import org.springframework.context.support.*;
public class SpringTest
{
	public static void main(String[] args)
	{
		// 以类加载路径下的配置文件创建ClassPathResource实例
		ApplicationContext ctx = new ClassPathXmlApplicationContext("codeEETest/beans.xml");
		Being b1 = ctx.getBean("dog" , Being.class);
		b1.testBeing();
		Being b2 = ctx.getBean("cat" , Being.class);
		b2.testBeing();
	}
//结果:
我是狗,狗爱啃骨头
我是猫,猫喜欢吃老鼠
小结:
核心配置为:(静态工厂,由工厂获得类和注入依赖在一个bean中)
<bean id="dog"  class="codeEETest.BeingFactory"  factory-method="getBeing">

<!-- 配置静态工厂方法的参数 -->

<constructor-arg value="dog"/>

<!-- 驱动Spring以"我是狗"为参数来执行dog的setMsg()方法 -->

<property name="msg" value="我是狗"/>

</bean>

三、实例工厂方法创建bean

实例工厂方法与静态工厂方法只有一点不同:
静态工厂只需使用工厂类即可生产bean,实例工厂方法需要工厂实例。
配置静态工厂方法使用class指定静态工厂类,而配置实例工厂方法则使用factory-bean指定工厂类。
判断静态工厂与实例工厂,看工厂类的方法是不是static即可。

接口:

package codeEETest;
public interface Person
{
// 定义一个打招呼的方法
public String sayHello(String name);
// 定义一个告别的方法
public String sayGoodBye(String name);
}
实现类1:

package codeEETest;
public class Chinese implements Person
{
// 实现Person接口必须实现如下两个方法
public String sayHello(String name)
{
return name + ",您好";
}
public String sayGoodBye(String name)
{
return name + ",下次再见";
}
}
实现类2:

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

package codeEETest;
public class PersonFactory
{
// 获得Person实例的实例工厂方法
// ethnic参数决定返回哪个Person实现类的实例
public Person getPerson(String ethnic)
{
if (ethnic.equalsIgnoreCase("chin"))
{
return new Chinese();
}
else
{
return new American();
}
}
}
xml:(先由一个bean获得工厂实例,再由一个bean生产所要的对象)

<!-- 配置工厂Bean,该Bean负责产生其他Bean实例 -->
<bean id="personFactory" class="codeEETest.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>
测试:

package codeEETest;


import org.springframework.context.*;
import org.springframework.context.support.*;


public class SpringTest
{
public static void main(String[] args)
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("codeEETest/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"));
}
}
结果:
Mary,您好
Mary,下次再见
Jack,Hello!
Jack,Good Bye!
核心配置:(先得到工厂bean,再获得bean)
<!-- 配置工厂Bean,该Bean负责产生其他Bean实例 -->
<bean id="personFactory" class="codeEETest.PersonFactory"/>


<bean
id="chinese" factory-bean="personFactory" factory-method="getPerson">
<!-- 配置实例工厂方法的参数 -->
<constructor-arg value="chin"/>
</bean>





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值