10--Spring实例化bean的三种方式

上一篇我们已经搭建了一个新的Gradle模块,接下来我们就要分析IoC容器实例化Bean的过程,在此之前,先来温习一下Spring实例化bean的三种方式,构造函数实例化,静态工厂实例化,工厂实例化

1.构造函数实例化

构造函数实例化是最常见也是最简单的一种实例化bean的方式,该方式也有两种使用方法

  • 默认构造函数实例化
  • 指定构造函数实例化

我们先来分析默认构造函数实例化

1.1 默认构造函数实例化
  • 创建一个接口及其实现类作为bean
package org.springframework.beans;

/**
 * @author LiYanChao
 * @since 4.3
 */
public interface HelloApi {

    void sayHello();

    void sayListNames();

    void saySetNames();

    void sayArrayNames();

    void sayMapNames();

    void sayPropertiesNames();
}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.springframework.util.CollectionUtils;

/**
 * 
 * @author LiYanChao
 * @since 4.3
 */
public class HelloImpl implements HelloApi {

    private String message;

    private String name;

    private List<String> listNames;

    private Set<String> setNames;

    private Properties propertiesNames;

    private Map<String, String> mapNames;

    private String[] arrayNames;

    public HelloImpl() {

    }

    public HelloImpl(String name) {
        this.name = name;
    }

    public HelloImpl(String name, String message) {
        this.name = name;
        this.message = message;
    }

    public void sayArrayNames() {
        System.out.println("DI array properties");
        if (arrayNames != null && arrayNames.length > 0) {
            for (int i = 0; i < arrayNames.length; i++) {
                System.out.println(arrayNames[i]);
            }
        }
        System.out.println();
    }

    public void sayMapNames() {
        if (null != mapNames && mapNames.size() > 0) {
            System.out.println("DI map properties");
            for (Map.Entry<String, String> entry : mapNames.entrySet()) {
                System.out.println("key= " + entry.getKey() + " value= "
                        + entry.getValue());
            }
            System.out.println();
        }
    }

    public void sayPropertiesNames() {
        if (null != propertiesNames) {
            System.out.println("DI properties properties");
            System.out.println(propertiesNames.get("name"));
            System.out.println(propertiesNames.get("age"));
            System.out.println();
        }
    }

    public void sayListNames() {
        if (!CollectionUtils.isEmpty(listNames)) {
            System.out.println("DI list properties");
            for (String string : listNames) {
                System.out.println(string);
            }
            System.out.println();
        }
    }

    public void saySetNames() {
        if (!CollectionUtils.isEmpty(setNames)) {
            System.out.println("DI set properties");
            Iterator<String> iterator = setNames.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
            System.out.println();
        }
    }

    @Override
    public void sayHello() {
        System.out.println(message + name);
    }
    // 省略get/set方法
  • 在resources目录下新建myTestBean.xml配置文件
<!-- ====================实例化bean的方式Begin==================== -->
    <!-- 默认构造函数 -->
    <bean id="helloBean1" class="org.springframework.beans.HelloImpl"/> 
<!-- ====================实例化bean的方式End==================== -->
  • 新建测试用例
package org.springframework.test;

import org.junit.Before;
import org.junit.Test;
import org.springframework.beans.HelloApi;
import org.springframework.beans.HelloImpl;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.util.Assert;

import static org.junit.Assert.assertEquals;

/**
 * @author LiYanChao
 * @since 4.3
 */
public class BeanTest {

    private XmlBeanFactory xmlBeanFactory;

    HelloApi helloApi;

    @Before
    public void initXmlBeanFactory() {
        xmlBeanFactory = new XmlBeanFactory(new ClassPathResource("myTestBean.xml"));
    }

    @Test
    public void testDefaultConstructor() {
        helloApi = xmlBeanFactory.getBean("helloBean1", HelloImpl.class);
        System.out.println(helloApi);
    }

}
1.2 指定构造函数实例化
  • 配置文件
<!-- 指定构造器实例化 -->
<bean id="helloBean2" class="org.springframework.beans.HelloImpl">
    <!-- 指定构造器参数 index对应构造器中参数的位置 -->
    <constructor-arg index="0" value="I am a constructor"/>
    <constructor-arg index="1" value="Hello, "/>
</bean>
  • 测试用例
@Test
public void testConstructor() {
    helloApi = xmlBeanFactory.getBean("helloBean2", HelloImpl.class);
    helloApi.sayHello();
}

输出Hello, I am a constructor

2. 静态工厂实例化
  • Bean

package org.springframework.beans;

/**
 * 
 * @author LiYanChao
 * @since 4.3
 */
public class HelloApiStaticFactory {

    // 静态工厂方法
    public static HelloApi newInstance(String name, String message) {
        // 返回需要的Bean实例
        return new HelloImpl(name, message);
    }
}
  • 配置文件
<!-- 静态工厂方法实例化 -->
<bean id="helloBean3" class="org.springframework.beans.HelloApiStaticFactory" factory-method="newInstance">
    <!-- 指定构造器参数 index对应构造器中参数的位置 -->
    <constructor-arg index="0" value="I am a static factory"/>
    <constructor-arg index="1" value="Hello, "/>
</bean>
  • 测试用例
@Test
public void testStaticFactory() {
    helloApi = xmlBeanFactory.getBean("helloBean3", HelloImpl.class);
    helloApi.sayHello();
}

输出Hello, I am a static factory

3.实例工厂方法实例化
  • bean
package org.springframework.beans;

/**
 * 
 * @author LiYanChao
 * @since 4.3
 */
public class HelloApiInstanceFactory {

    // 工厂方法
    public HelloApi newInstance(String name, String message) {
        return new HelloImpl(name, message);
    }
}
  • 配置文件
<!-- 实例工厂方法实例化 -->
<bean id="helloApiInstanceFactory" class="org.springframework.beans.HelloApiInstanceFactory"/>
<!-- 不能指定class属性,此时必须使用factory-bean属性来指定工厂Bean,factory-method属性指定实例化Bean的方法 -->
<bean id="helloBean4" factory-bean="helloApiInstanceFactory" factory-method="newInstance">
    <constructor-arg index="0" value="I am a instance factory"/>
    <constructor-arg index="1" value="Hello, "/>
</bean>
  • 测试用例
@Test
public void testFactory() {
    helloApi = xmlBeanFactory.getBean("helloBean4", HelloImpl.class);
    helloApi.sayHello();
}

输出:Hello, I am a instance factory

Spring实例化bean的三种方式就讲到这里了,比较简单,但是其中的源码细节比较复杂,会在接下来的博客中分析

猜你喜欢

转载自blog.csdn.net/lyc_liyanchao/article/details/82388479