创建bean通常有如下方法:
1.调用构造器创建一个bean实例。
2.BeanFactory调用某个类的静态工厂方法创建bean.
3.BeanFactory调用实例工厂方法创建bean.
先来说说---调用构造器创建一个bean实例。
通过“new”关键字创建bean实例是最常见的情形,如果采用设值注入的方式,则要求该类提供无参数的构造器。
BeanFactory将调用该构造器来创建bean实例,该实例是个默认的实例。
接下来,BeanFactory会根据配置文件来决定依赖关系:首先实例化依赖的bean,然后为bean注入依赖关系;最后将一个完整的Bean实例返回给程序。
for example:
---------------------------------------------------------------------------------
package org.viking.spring.itf;
public interface Person
{
public void useAxe();
}
----------------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.Axe;
import org.viking.spring.itf.Person;
public class Chinese implements Person {
private Axe axe;
public Chinese()
{
System.out.println("Spring 实例化主调bean: chinese实例....");
}
public void useAxe()
{
System.out.println(axe.chop());
}
public void setAxe(Axe axe)
{
System.out.println("spring 执行依赖关系注入....");
this.axe = axe;
}
public Axe getAxe() {
return axe;
}
}
----------------------------------------------------------------------------------
package org.viking.spring.itf;
public interface Axe
{
public String chop();
}
----------------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.Axe;
public class SteelAxe implements Axe {
public SteelAxe()
{
System.out.println("Spring 实例化依赖bean: SteelAxe实例...");
}
public String chop()
{
return "钢斧砍材真快";
}
}
----------------------------------------------------------------------------------
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="chinese" class="org.viking.spring.imp.Chinese">
<property name="axe">
<ref local="steelAxe"/>
</property>
</bean>
</beans>
----------------------------------------------------------------------------------
package org.viking.spring.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.viking.spring.itf.Being;
import org.viking.spring.itf.People;
import org.viking.spring.itf.Person;
import junit.framework.TestCase;
public class BeanTest extends TestCase
{
public void testNewBean()throws Exception
{
ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println("程序已经实例化BeanFactory...");
Person p = (Person)app.getBean("chinese");
System.out.println("程序中已经完成了chinese bean 的实例化...");
p.useAxe();
}
}
----------------------------------------------------------------------------------
执行结果清楚地反应了执行过程:
(1)创建BeanFactory实例。
(2)调用Chinese类的默认构造器创建默认实例。
(3)根据配置文件注入依赖关系:先实例化依赖bean,然后将依赖bean注入。
(4)返回一个完整的javabean实例。
接下来说说---使用静态工厂方法创建bean
反正这种方法,按书上我是没验证通过,去CSDN上求解,也毫无结果!但是还是写出来吧!
使用静态工厂方法创建bean实例时,class属性也时必须的,但此时class属性并不是该实现类,而是静态工厂类。由于spring需要知道由哪个静态工厂方法来创建bean实例,因此使用factory-method属性来确定静态工厂方法名,在之后的过程中,spring的处理步骤与采用其他方法的创建完全一样。
注意:这个Bean定义并没有指定返回对象的类型,只指定静态工厂类。该方法必须是静态的,如果静态工厂方法需要参数,则使用<constructor-arg>元素将其导入。
下面是书上的代码---我没成功!
---------------------------------------------------------------------------------
package org.viking.spring.itf;
public interface Being
{
public void testBeing();
}
-----------------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.Being;
public class Cat implements Being {
private String msg;
public void testBeing()
{
System.out.println(msg + "猫爱吃鱼! ");
}
public void setMsg(String msg)
{
this.msg = msg;
}
}
-------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.Being;
public class Dog implements Being {
private String msg;
public void setMsg(String msg) {
this.msg = msg;
}
public void testBeing()
{
System.out.println(msg + "狗爱啃骨头! ");
}
}
--------------------------------------------------------------
package org.viking.spring.factory;
import org.viking.spring.imp.Cat;
import org.viking.spring.imp.Dog;
import org.viking.spring.itf.Being;
public class BeingFactory
{
public static Being getBeing(String arg)
{
if(arg.equalsIgnoreCase( "dog "))
return new Dog();
else
return new Cat();
}
}
-----------------------------------------------------------
applicationContext.xml:
<?xml version= "1.0 " encoding= "UTF-8 "?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN " "http://www.springframework.org/dtd/spring-beans.dtd ">
<beans>
<bean id= "dog " class= "org.viking.spring.factory.BeingFactory " factory-method= "getBeing ">
<constructor-arg>
<value> dog </value>
</constructor-arg>
<property name= "msg ">
<value> 我是狗 </value>
</property>
</bean>
<bean id= "cat " class= "org.viking.spring.factory.BeingFactory " factory-method= "getBeing ">
<constructor-arg>
<value> cat </value>
</constructor-arg>
<property name= "msg ">
<value> 我是猫 </value>
</property>
</bean>
</beans>
---------------------------------------------------------------------------------------------------------
package org.viking.spring.test;
import java.io.FileInputStream;
import java.io.InputStream;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.InputStreamResource;
import org.viking.spring.itf.Being;
import org.viking.spring.itf.Person;
import junit.framework.TestCase;
public class BeanTest extends TestCase
{
public void testStaticFactoryBean()
{
ApplicationContext context= new ClassPathXmlApplicationContext( "applicationContext.xml ");
System.out.println( "程序已经实例化BeanFactory... ");
Being b1 = (Being)context.getBean( "dog ");
b1.testBeing();
Being b2 = (Being)context.getBean( "cat ");
b2.testBeing();
}
}
-------------------------------------------------------------------------
吼吼,还请高手指点一下,看看上面的代码要怎么改?
对了,是applicationContext.xml出现小红叉,提示:
No setter found for property 'msg' in class 'org.viking.spring.factory.BeingFactory'
好,来说说最后一种方式---调用实例工厂方法创建bean
实例工厂方法必须提供工厂实例,因此必须在配置文件中配置工厂实例,而bean元素无需class属性。
采用实例工厂方法创建bean的配置需要如下两个属性:
1、factory-bean:该属性的值为工厂bean的id.
2、factory-method:该方法负责生成bean实例。
for example:
-----------------------------------------------------------------------------
package org.viking.spring.itf;
public interface People
{
public void sayHello();
public void sayGoodBye();
}
-----------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.People;
public class AmericanPeople implements People {
private String name;
public void sayGoodBye()
{
System.out.println(name + " , Hello!");
}
public void sayHello()
{
System.out.println(name + ", GoodBye!");
}
public void setName(String name) {
this.name = name;
}
}
-----------------------------------------------------------------------------
package org.viking.spring.imp;
import org.viking.spring.itf.People;
public class ChinesePeople implements People {
private String name;
public void sayGoodBye()
{
System.out.println(name + ",您好!");
}
public void sayHello()
{
System.out.println(name + ",再见!");
}
public void setName(String name) {
this.name = name;
}
}
-----------------------------------------------------------------------------
package org.viking.spring.factory;
import org.viking.spring.imp.AmericanPeople;
import org.viking.spring.imp.ChinesePeople;
import org.viking.spring.itf.People;
public class PeopleFactory
{
public People getPeople(String people)
{
if(people.equalsIgnoreCase("china"))
return new ChinesePeople();
else
return new AmericanPeople();
}
}
-----------------------------------------------------------------------------
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="peopleFactory" class="org.viking.spring.factory.PeopleFactory"></bean>
<bean id="getChinesePeople" factory-bean="peopleFactory" factory-method="getPeople">
<constructor-arg>
<value>china</value>
</constructor-arg>
<property name="name">
<value>张三</value>
</property>
</bean>
<bean id="getAmericanPeople" factory-bean="peopleFactory" factory-method="getPeople">
<constructor-arg>
<value>1</value>
</constructor-arg>
<property name="name">
<value>sum</value>
</property>
</bean>
</beans>
-----------------------------------------------------------------------------
调用实例工厂方法创建bean,与调用静态工厂方法创建bean的用法基本相似。区别如下:
1.调用实例工厂方法创建bean时,必须将实例工厂配置成bean实例。而静态工厂方法则无需配置工厂bean.
2.调用实例工厂方法创建bean时,必须使用factory-bean属性来确定工厂bean.而静态工厂方法则使用class元素确定静态工厂类。
相同之处:
1.都需要使用factory-method属性指定生产bean实例的工厂方法。
2.工厂方法如果需要参数,都使用constructor-arg属性确定参数值。
3.其他依赖注入属性,都使用property元素确定参数值。