• 实例化Bean的方法(基于xml配置)-http://blog.csdn.net/shymi1991/article/details/48153293


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

    标签: spring framework
     分类:

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

    创建的方法有三种:

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

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

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

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

    例子:

    接口HelloApi.Java

    [java] view plain copy
     
    1. package com.szse.beans;  
    2.   
    3. public interface HelloApi {  
    4.       
    5.     public void sayHello();  
    6.   
    7. }  

    它的实现类HelloApiImpl.java

    [java] view plain copy
     
    1. package com.szse.beans;  
    2.   
    3. public class HelloApiImpl implements HelloApi{  
    4.   
    5.     private int num;  
    6.     private String message;  
    7.       
    8.     public HelloApiImpl(){  
    9.         num = 1;  
    10.         message = "Hello world!";   
    11.     }  
    12.       
    13.     @Override  
    14.     public void sayHello() {  
    15.   
    16.         System.out.println(num + ":" + message);  
    17.   
    18.     }  
    19. }  
    配置文件HelloWorld.xml
    [html] view plain copy
     
    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    
    3.       xmlns="http://www.springframework.org/schema/beans"    
    4.       xsi:schemaLocation="http://www.springframework.org/schema/beans   
    5.       http://www.springframework.org/schema/beans/spring-beans-4.2.xsd">     
    6.   
    7. <bean id="firstBean" class="com.szse.beans.HelloApiImpl ">   
    8. </bean>  
    9. </beans>  
    单元测试类TestHello.java
    [java] view plain copy
     
    1. package com.szse.beans;  
    2.   
    3. import org.junit.Test;  
    4. import org.springframework.context.ApplicationContext;  
    5. import org.springframework.context.support.ClassPathXmlApplicationContext;  
    6.   
    7. public class TestHello {  
    8.     @Test  
    9.     public void testInstantiatingBeanByConstructor() {  
    10.         //使用构造器  
    11.         ApplicationContext ctx =   
    12.     new ClassPathXmlApplicationContext("HelloWorld.xml");  
    13.         HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);  
    14.         firstBean.sayHello();  
    15.     }  
    16. }  
    输出 1:Hello world!
     
    1.2 带参构造器,类中有带参的构造方法
    ①根据参数索引(index)
    <bean id="beanID" class="com.szse.beans.HelloApiImpl "> 
          <constructor-arg  index=" " value=" "/>
    </bean>
    index表示构造器的第几个参数,从0开始,value即为该参数的值。
    例子:
    在HelloApiImpl.java添加
    [java] view plain copy
     
    1. public HelloApiImpl(int num,String message){  
    2.         this.num = num;  
    3.         this.message = message;   
    4.     }  
    在HelloWorld.xml文件中添加
    [html] view plain copy
     
    1. <bean id="secondBean" class="com.szse.beans.HelloApiImpl ">    
    2.     <constructor-arg index="0" value="2" />  
    3.     <constructor-arg index="1" value="Hello spring!" />  
    4. </bean>  
    在TestHello.java的测试方法,保留第一个例子作为对比
    [java] view plain copy
     
    1. @Test  
    2.     public void testInstantiatingBeanByConstructor() {  
    3.         //使用构造器  
    4.         ApplicationContext ctx =   
    5.     new ClassPathXmlApplicationContext("HelloWorld.xml");  
    6.         HelloApi firstBean = ctx.getBean("firstBean", HelloApi.class);  
    7.         firstBean.sayHello();  
    8.         HelloApi secondBean = ctx.getBean("secondBean", HelloApi.class);  
    9.         secondBean.sayHello();  
    10.     }  


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

    ②根据参数类型(type)

    将上面的secondBean配置改为如下

    [html] view plain copy
     
    1. <bean id="secondBean" class="com.szse.beans.HelloApiImpl ">    
    2.     <constructor-arg type="int" value="2" />  
    3.     <constructor-arg type="java.lang.String" value="Hello spring!" />  
    4. </bean>  

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

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

    ③根据参数名(name)

    将上面的secondBean配置改为如下

    [html] view plain copy
     
    1. <bean id="secondBean" class="com.szse.beans.HelloApiImpl ">    
    2.     <constructor-arg name="num" value="2" />  
    3.     <constructor-arg name="message" value="Hello spring!" />  
    4. </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

     

    [java] view plain copy
     
    1. package com.szse.beans;  
    2.   
    3. public class HelloApiStaticFactory {  
    4.     //工厂方法  
    5.     public static HelloApi newInstance(int num,String message) {  
    6.     //返回需要的Bean实例  
    7.     return new HelloApiImpl(num,message);  
    8.     }  
    9. }  

    xml中加上

     

    [html] view plain copy
     
    1. <bean id="thirdBean" class="com.szse.beans.HelloApiStaticFactory" factory-method="newInstance">    
    2.     <constructor-arg name="num" value="3" />  
    3.     <constructor-arg name="message" value="Hello Jane!" />  
    4. </bean>  


    测试类中加上方法

     

    [java] view plain copy
     
    1. @Test  
    2.     public void testInstantiatingBeanByFactory() {  
    3.             //使用工场方法  
    4.         ApplicationContext ctx =   
    5.         new ClassPathXmlApplicationContext("HelloWorld.xml");  
    6.         HelloApi thirdBean = ctx.getBean("thirdBean", HelloApi.class);  
    7.         thirdBean.sayHello();  
    8.     }  


    输出结果: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

    [java] view plain copy
     
    1. package com.szse.beans;  
    2.   
    3. public class HelloApiInstanceFactory {  
    4.     public HelloApi newInstance(int num,String message) {  
    5.            return new HelloApiImpl(num,message);  
    6.        }  
    7. }  

    xml文件中加入

    [html] view plain copy
     
    1. <bean id="instanceFactoryBean" class="com.szse.beans.HelloApiInstanceFactory"/>  
    2. <bean id="fourthBean" factory-bean="instanceFactoryBean" factory-method="newInstance">    
    3.     <constructor-arg name="num" value="4" />  
    4.     <constructor-arg name="message" value="Hello Tom!" />  
    5. </bean>  

    测试方法testInstantiatingBeanByFactory加入

    [java] view plain copy
     
    1. HelloApi fourthBean = ctx.getBean("fourthBean", HelloApi.class);  
    2. fourthBean.sayHello();  
    输出结果 4:Hello Tom!

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

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

  • 相关阅读:
    Spring学习笔记之四----基于Annotation的Spring AOP编程
    Spring学习笔记之三----基于Annotation的Spring IOC配置
    Spring学习笔记之一----基于XML的Spring IOC配置
    Spring学习笔记之二----基于XML的Spring AOP配置
    Swift语言之类型方法
    Swift语言之命令模式(Command Pattern)实现
    用Swift语言做App开发之单元测试
    Spring Batch学习笔记三:JobRepository
    Spring Batch学习笔记二
    初探Spring Batch
  • 原文地址:https://www.cnblogs.com/anruy/p/7298217.html
Copyright © 2020-2023  润新知