Spring容器的三种实例化Bean的方式

Spring容器提供了无参数构造器,静态工厂方法(简单工厂模式和使用实例工厂方法(工厂方法模式)三种方式来实例化Bean。

1 默认无参数构造器实例化Bean

自定义Bean IDCardGenerator 说明:

IDCardGenerator类中主要包含了:
属性: Long和String以及Date类型的数据类型,其中Date类型的数据类型需要手动处理
getset方法:Spring依赖注入时通过set方法给属性赋值
默认无参数的构造器:用于创建Bean的实例
带三个参数的构造器:Spring依赖注入时通过构造器给属性复制
toString()方法:用于获取Bean信息

package com.timeline.javaweb.spring.bean;

import com.timeline.javaweb.spring.utils.lang.DateFormatConstants;
import com.timeline.javaweb.spring.utils.lang.DateUtils;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/** * IDCard生成器,用于SpringIOC测试数据 * * @author tony * @create 2016-03-13-8:18 * @since JDK7.0u80 */
public class IDCardGenerator {

    private String prefix; //身份证前缀

    private Date birthday; //生日

    private Long number; //编号

    /*get set方法*/

    public String getPrefix() {
        return prefix;
    }

    public void setPrefix(String prefix) {
        this.prefix = prefix;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Long getNumber() {
        return number;
    }

    public void setNumber(Long number) {
        this.number = number;
    }

    /** * 带参数的构造器 * @param prefix * @param year * @param month * @param day * @param number */
    public IDCardGenerator(String prefix,int year,int month,int day, Long number) {
        this.prefix = prefix;
        Calendar instance =new GregorianCalendar(year,month,day);
        this.birthday =instance.getTime();
        this.number = number;
    }

    /** * 默认的构造器 */
    public IDCardGenerator(){}

    /** * 身份证的描述 * @return */
    @Override
    public String toString() {
        return "IDCardGenerator{" +
                "prefix='" + prefix + '\'' +
                ", birthday=" + DateUtils.date2String(birthday, DateFormatConstants.YYYY_MM_DD)+
                ", number=" + number +
                '}';
    }
}

appContext-ioc.xml配置文件的配置信息

  <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd ">

    <!--在Spring容器中装配一个Bean,它会用默认无参数的构造器反射创建Bean的实例,默认作用域是单例的 -->
<bean id="defaultConstructor" class="com.timeline.javaweb.spring.bean.IDCardGenerator" scope="singleton"/>


</beans>

测试用例

      @Test
    /** * 默认无参数构造器创建Bean的实例 */
  public void testInstanceBeanWithDefaultConstrutor()throws Exception{

     IDCardGenerator defaultConstructor=   SpringUtils.getSeviceBean("defaultConstructor",IDCardGenerator.class);

        logger.info("默认无参数构造器实例化Bean的结果"+defaultConstructor);

        IDCardGenerator idCardGenerator=SpringUtils.getSeviceBean("defaultConstructor",IDCardGenerator.class);
        Assert.assertEquals(defaultConstructor,idCardGenerator);
    }

2 静态工厂方法实例化Bean-简单工厂模式

自定义Bean说明:

package com.timeline.javaweb.spring.bean.product;

import com.google.common.base.MoreObjects;

/** * Product Bean * * @author tony * @create 2016-04-10-9:11 * @since JDK7.0u80 */
public abstract class Product {
    private String name;
    private Double price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public Product() {

    }

    public Product(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("name", name)
                .add("price", price)
                .toString();
    }
}

子类Car

import com.google.common.base.MoreObjects;

/** * Car Bean * * @author tony * @create 2016-04-10-9:29 * @since JDK7.0u80 */
public class Car extends Product {

    private boolean rechargeable; //是否能充电

    public boolean isRechargeable() {
        return rechargeable;
    }

    public void setRechargeable(boolean rechargeable) {
        this.rechargeable = rechargeable;
    }

    public Car() {
    }

    public Car(boolean rechargeable) {
        this.rechargeable = rechargeable;
    }

    public Car(String name, Double price, boolean rechargeable) {
        super(name, price);
        this.rechargeable = rechargeable;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("rechargeable", rechargeable)
                .add("name", super.getName())
                .add("price", super.getPrice())
                .toString();
    }
}

子类MobilePhone

package com.timeline.javaweb.spring.bean.product;

import com.google.common.base.MoreObjects;

/** * MobilePhone Bean * * @author tony * @create 2016-04-10-9:31 * @since JDK7.0u80 */
public class MobilePhone extends Product{

    private boolean isTouchID; //是否带TouchIDdd

    public boolean isTouchID() {
        return isTouchID;
    }

    public void setTouchID(boolean touchID) {
        isTouchID = touchID;
    }

    public MobilePhone(){}

    public MobilePhone(boolean isTouchID) {
        this.isTouchID = isTouchID;
    }

    public MobilePhone(String name, Double price, boolean isTouchID) {
        super(name, price);
        this.isTouchID = isTouchID;
    }


    @Override
    public String toString() {
        return MoreObjects.toStringHelper(this)
                .add("isTouchID", isTouchID)
                .add("name",super.getName())
                .add("price",super.getPrice())
                .toString();
    }
}

在自定义类Product,Car和MobilePhone中使用了Google的核心Java库Guava,配置POM.xml文件中如下所示:

<properties>
        <guava.verison>19.0</guava.verison>
    </properties>

 <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.verison}</version>
        </dependency>

工厂方法实现类:ProductCreator

package com.timeline.javaweb.spring.bean.product.factory;

import com.timeline.javaweb.spring.bean.product.Car;
import com.timeline.javaweb.spring.bean.product.MobilePhone;
import com.timeline.javaweb.spring.bean.product.Product;

import java.util.Map;

/** * Product Factory * * @author tony * @create 2016-04-10-9:21 * @since JDK7.0u80 */
public class ProductCreator {
    /** * 根据产品ID创建产品(静态工厂方法实例化-简单工厂模式) * * @param productId * @return */
    public static Product createProduct(String productId) {

        if ("iphone6s".equals(productId)) {
            return new MobilePhone("iphone6s", 6088.00, true);
        } else if ("tesla".equals(productId)) {
            return new Car("tesla", 1000000.0, true);
        }
        throw new IllegalArgumentException("Unknown Product");

    }

}

appContext-ioc.xml配置文件的配置信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd ">


    <!-- 使用静态方法创建Bean-->

    <bean id="iphone6sWithStaticFactoryMethod" class="com.timeline.javaweb.spring.bean.product.factory.ProductCreator" factory-method="createProduct">
        <constructor-arg value="iphone6s"/>
    </bean>
    <!-- 声明一个静态方法创建的Bean,需要在Class属性中指定工厂方法的实现类, 在factory-method属性中指定工厂方法的名称,最后使用constructor-arg元素传递参数-->
    <bean id="teslaWithStaticFactoryMethod" class="com.timeline.javaweb.spring.bean.product.factory.ProductCreator" factory-method="createProduct">
        <constructor-arg value="tesla"/>
    </bean>



</beans>

静态工厂方法实例化Bean测试用例

   @Test
    /** * 静态工厂方法创建Bean的实例 */
    public void testInstanceBeanWithStaticFactoryMethod()throws Exception{
        Product iphone6s =SpringUtils.getSeviceBean("iphone6sWithStaticFactoryMethod", MobilePhone.class);
        logger.info("iphone6s info " +iphone6s);

        Product tesla=SpringUtils.getSeviceBean("teslaWithStaticFactoryMethod",Car.class);
        logger.info("tesla car info " +tesla);
    }

    public void testInstanceBeanWithInstanceFactoryMethod()throws Exception{
        Product iphone6s =SpringUtils.getSeviceBean("iphone6s", MobilePhone.class);
        logger.info("iphone6s info " +iphone6s);
    }

测试用例采用Junit4框架实现,POM.xml配置文件如下所示:

   <properties>

        <junit.version>4.11</junit.version>
    </properties>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>

同时还加入了Apache Log4j2作为日志框架,用于记录程序运行的结果信息,POM.xml配置文件如下所示:

   <properties>

        <log42j.version>2.5</log42j.version>

    </properties>
       <!-- apache log4j2 -->

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>${log42j.version}</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>${log42j.version}</version>
        </dependency>

关于Log4j的详细使用和配置可以参考Log4j的详细使用和配置链接点我!!!

2016-04-10 11:20:29.645 INFO [main][TestSequenceGenerator.java:52] - iphone6s info MobilePhone{isTouchID=true, name=iphone6s, price=6088.0}
2016-04-10 11:20:29.647 INFO [main][TestSequenceGenerator.java:55] - tesla car info Car{rechargeable=true, name=tesla, price=1000000.0}

3 实例工厂方法实例化Bean-工厂方法模式

实例工厂实现类:ProductCreator

package com.timeline.javaweb.spring.bean.product.factory;

import com.timeline.javaweb.spring.bean.product.Car;
import com.timeline.javaweb.spring.bean.product.MobilePhone;
import com.timeline.javaweb.spring.bean.product.Product;

import java.util.Map;

/** * Product Factory * * @author tony * @create 2016-04-10-9:21 * @since JDK7.0u80 */
public class ProductCreator {


    /** * Map容器用于存放FactoryBean创建的Product对象 */
    private Map<String,Product> productMap;


    /** * set方法实现Spring容器的依赖注入 * @param productMap */
    public void setProductMap(Map<String, Product> productMap) {
        this.productMap = productMap;
    }


    /** * 根据产品ID从Spring容器中获取指定的Product对象(实例工厂方法实例化-工厂方法模式) * @param productId * @return */
    public Product createProductInstance(String productId){
        Product product =productMap.get(productId);
        if(product!=null){
            return product;
        }
        throw new IllegalArgumentException("Unknow product");
    }
}

appContext-ioc.xml配置文件的配置信息

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd ">

    <!-- 填充productMap数据-->

    <!-- 使用Spring支持的属性注入的方式注入两个Product抽象父类的子类对象 -->
    <bean id="carBean" class="com.timeline.javaweb.spring.bean.product.Car" p:name="tesla" p:price="1200000.0" p:rechargeable="true"/>
    <bean id="mobilePhoneBean" class="com.timeline.javaweb.spring.bean.product.MobilePhone" p:name="iphone6sPlus" p:price="7088.0" p:touchID="true"/>


    <!--使用util命名空间定义一个Map,并引用之前定义的两个Product对象-->
    <util:map id="productMap" map-class="java.util.HashMap" >
        <entry key="mobilePhoneBean" value-ref="mobilePhoneBean"/>
        <entry key="carBean" value-ref="carBean"/>
    </util:map>

    <!-- 创建工厂Bean对象,封装两个对象到Map容器中-->
    <bean id="productCreator" class="com.timeline.javaweb.spring.bean.product.factory.ProductCreator">
        <property name="productMap">
            <ref bean="productMap"/>
        </property>
    </bean>


    <bean id="mobilePhoneWithInstacneFactoryMethod " factory-bean="productCreator" factory-method="createProductInstance">
        <constructor-arg value="mobilePhoneBean"/>
    </bean>
    <bean id="carWithInstanceFactoryMethod" factory-bean="productCreator" factory-method="createProductInstance">
        <constructor-arg value="carBean"/>
    </bean>

</beans>

实例工厂方法实例化Bean测试用例

 @Test
    public void testInstanceBeanWithInstanceFactoryMethod()throws Exception{
        //获取实例工厂对象
        ProductCreator  productCreator  =SpringUtils.getSeviceBean("productCreator",ProductCreator.class);
        //调用创建Product对象的方法
        Product iphone6s =productCreator.createProductInstance("mobilePhoneBean");
        logger.info("iphone6s info " +iphone6s);
    }

程序运行结果

2016-04-10 14:01:14.761 INFO [main][TestSequenceGenerator.java:64] - iphone6s info MobilePhone{isTouchID=true, name=iphone6sPlus, price=7088.0}

欢迎扫描下方的二维码,关注微信公众服务号-艺无止境,分享IT技术干货。
Spring容器的三种实例化Bean的方式_第1张图片

你可能感兴趣的:(Spring容器的三种实例化Bean的方式)