关闭

spring 创建bean的三种方式.

标签: beanspringimportclassstringinterface
1047人阅读 评论(0) 收藏 举报
分类:
创建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元素确定参数值。

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    最新评论