天天看点

spring 创建bean的三种方式.

创建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元素确定参数值。