实例化Bean的方法(基于xml配置)


Spring IoC容器 根据基于xml的配置元数据(configuration metadata),使用反射机制来创建Bean的实例。

创建的方法有三种:

1. 通过构造器<constructor-arg/>

1.1 使用空构造器进行定义。类中必须有空构造器(可以是默认的)

空构造器中没有传入参数,bean的配置只需要一个定义名就可以了。

<bean id="beanID" class="com.szse.beans.HelloApiImpl "> </bean>

例子:

接口HelloApi.java


package com.szse.beans;

public interface HelloApi {
	
	public void sayHello();

}

它的实现类HelloApiImpl.java

package com.szse.beans;

public class HelloApiImpl implements HelloApi{

	private int num;
	private String message;
	
	public HelloApiImpl(){
		num = 1;
		message = "Hello world!"; 
	}
	
	@Override
	public void sayHello() {

		System.out.println(num + ":" + message);

	}
}

配置文件HelloWorld.xml
<?xml version="1.0" encoding="UTF-8"?>
<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.2.xsd">   

<bean id="firstBean" class="com.szse.beans.HelloApiImpl "> 
</bean>
</beans>
单元测试类TestHello.java
package com.szse.beans;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestHello {
	@Test
	public void testInstantiatingBeanByConstructor() {
		//使用构造器
		ApplicationContext ctx = 
	new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);
		firstBean.sayHello();
	}
}
输出 1:Hello world!

1.2 带参构造器, 类中有带参的构造方法
①根据参数索引(index)
<bean id="beanID" class="com.szse.beans.HelloApiImpl "> 
      <constructor-arg  index=" " value=" "/>
</bean>
index表示构造器的第几个参数,从0开始,value即为该参数的值。
例子:
在HelloApiImpl.java添加
public HelloApiImpl(int num,String message){
		this.num = num;
		this.message = message; 
	}

在HelloWorld.xml文件中添加
<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg index="0" value="2" />
	<constructor-arg index="1" value="Hello spring!" />
</bean>
在TestHello.java的测试方法,保留第一个例子作为对比
@Test
	public void testInstantiatingBeanByConstructor() {
		//使用构造器
		ApplicationContext ctx = 
	new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);
		firstBean.sayHello();
		HelloApi secondBean = ctx.getBean("secondBean", HelloApi.class);
		secondBean.sayHello();
	}


输出1:Hello world!
       2:Hello spring!


②根据参数类型(type)

将上面的secondBean配置改为如下

<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg type="int" value="2" />
	<constructor-arg type="java.lang.String" value="Hello spring!" />
</bean>

若是java基础类型,type可以直接指定该类型,其他都要用全类名。

测试方法不变,大家可以自己运行一遍试试结果是否一样。



③根据参数名(name)

将上面的secondBean配置改为如下

<bean id="secondBean" class="com.szse.beans.HelloApiImpl ">  
	<constructor-arg name="num" value="2" />
	<constructor-arg name="message" value="Hello spring!" />
</bean>

测试方法不变,大家可以自己再运行一遍试试结果是否一样。


注:这里解释顺便给大家加深一下 对 “bean的实例是由IoC容器主动创建,而不是由我们自己创建”  这句话的理解。可以在构造器中加上System.out.println(”print sth…")。

测试方法中只保留这一句:

ApplicationContext ctx =
    new ClassPathXmlApplicationContext("HelloWorld.xml");

运行输出,看看是不是我们xml文件中配置了几个bean就会打印出几个“print sth…”。

所以,ApplicationContext加载XML文件时就会创建好所有bean的实例,我们用的时候只需要getBean()就可以了。


2. 使用静态工厂方法

<bean id="beanID" class="com.szse.beans.HelloApiStaticFactory"factory-method="newInstance">

 </bean>

注意这里的class属性是静态工厂类,而不是该bean的类。使用factory-method属性来确定哪个静态工厂方法创建的bean实例。

Spring调用工厂方法(也可以包含一组参数),并返回一个有效的对象。如果静态工厂方法需要参数,使用<constructor-arg>元素传入。

例子

静态工场类HelloApiStaticFactory.java

package com.szse.beans;

public class HelloApiStaticFactory {
	//工厂方法
	public static HelloApi newInstance(int num,String message) {
	//返回需要的Bean实例
	return new HelloApiImpl(num,message);
	}
}

xml中加上

<bean id="thirdBean" class="com.szse.beans.HelloApiStaticFactory" factory-method="newInstance">  
	<constructor-arg name="num" value="3" />
	<constructor-arg name="message" value="Hello Jane!" />
</bean>


测试类中加上方法

@Test
	public void testInstantiatingBeanByFactory() {
			//使用工场方法
		ApplicationContext ctx = 
		new ClassPathXmlApplicationContext("HelloWorld.xml");
		HelloApi thirdBean = ctx.getBean("thirdBean", HelloApi.class);
		thirdBean.sayHello();
	}


输出结果:3:Hello Jane!


3. 使用实例工场方法

先定义实例工厂Bean

<bean id="instanceFactoryBean" class="InstanceFactory全类名"/>

再使用实例工厂Bean创建我们需要的Bean,注意这里没有class属性了。若要传入指定方法参数,则和使用构造器方式一样。
<bean id="fourthBean" factory-bean="instanceFactoryBean" factory-method="newInstance"> </bean>

例子

实例工厂类HelloApiInstanceFactory.java

package com.szse.beans;

public class HelloApiInstanceFactory {
	public HelloApi newInstance(int num,String message) {
		   return new HelloApiImpl(num,message);
	   }
}

xml文件中加入

<bean id="instanceFactoryBean" class="com.szse.beans.HelloApiInstanceFactory"/>
<bean id="fourthBean" factory-bean="instanceFactoryBean" factory-method="newInstance">  
	<constructor-arg name="num" value="4" />
	<constructor-arg name="message" value="Hello Tom!" />
</bean>

测试方法testInstantiatingBeanByFactory加入

HelloApi fourthBean = ctx.getBean("fourthBean", HelloApi.class);
fourthBean.sayHello();
输出结果 4:Hello Tom!

这三种实例化Bean的方式只是配置不一样,从获取方式看完全一样。这三种方式都是基于XML配置文件,脱离xml文件

Spring容器还有基于注解(Annotation)的方式来创建Bean,这个我们以后会讲到。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值