Spring的IoC容器

2017-06-22  本文已影响0人  luoxn28

Spring是一个轻量级的Java开发框架,其提供的两大基础功能为IoC和AOP,其中IoC为依赖反转(Inversion of Control)。IOC容器的基本理念就是“为别人服务”,那为别人服务什么呢?其中最重要就是业务对象的构建管理和业务对象之间的依赖绑定

IoC容器管理业务对象,首先需要知道业务对象之间的依赖关系,以下有几种方式告诉IoC容器其管理的对象之间的绑定关系:

注意:不管是什么方式来告知IoC容器对象之间的绑定关系,最终都是通过编码方式(调用IOC提供的API)来将这些信息"写入"到IoC容器中的。

2种基本的容器类型

Spring的IoC容器提供两种基本的容器类型:BeanFactory和ApplicationContext。

依赖注入的3种方式

spring的bean配置(XML配置方式)

属性注入即通过 setter 方法注入Bean 的属性值或依赖的对象,使用 <property> 元素, 使用 name 属性指定 Bean 的属性名称,value 属性或 <value> 子节点指定属性值,属性注入是实际应用中最常用的注入方式。属性注入Bean类须有一个默认的构造方法。

<!-- Hello类中有一个String类型的msg属性 -->
<bean id="hello" class="com.luoxn28.Hello">
    <property name="msg" value="luoxn28"/>
</bean>

通过构造方法注入Bean 的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用,构造器注入在 <constructor-arg> 元素里声明属性。

<bean id="msg" class="java.lang.String">
    <constructor-arg value="string"/>
</bean>

<!-- 按照索引匹配入参 -->
<bean id="car" class="com.luoxn28.Car">
    <constructor-arg value="比亚迪" index="0"/>
    <constructor-arg value="中国制造" index="1"/>
    <constructor-arg value="200000" index="2"/>
</bean>
<!-- 按照类型匹配入参 -->
<bean id="car2" class="com.luoxn28.Car">
    <constructor-arg value="比亚迪" type="java.lang.String">
    <constructor-arg value="中国制造" type="java.lang.String"/>
    <constructor-arg value="200000" type="double"/>
</bean>

多个Bean依赖配置,需在Bean配置中指定对Bean的引用。既可以使用"ref"属性配置,也可以直接在属性里包含Bean的配置,即内部Bean。内部Bean只能在当前定义处使用,貌似其他地方也没法使用哈 :)

<bean id="msg" class="java.lang.String">
    <constructor-arg value="luoxn28"/>
</bean>

<!-- Hello类中有一个String类型的msg属性 -->
<bean id="hello" class="com.luoxn28.Hello">
    <property name="msg" ref="msg"/>
</bean>

<!-- Hello类中有一个String类型的msg属性 -->
<bean id="hello" class="com.luoxn28.Hello">
    <property name="msg">
        <bean class="java.lang.String">
            <constructor-arg value="luoxn28"/>
        </bean>
    </property>
</bean>

如果Bean属性是集合/容器类型,则通过<list>/<set>/<map>来配置。

<!-- CollectionClass类有3个属性,List<String> list、Set<String> set、Map<String, String> map-->
<bean id="collectionClass" class="com.luoxn28.CollectionClass">
    <property name="list">
        <list>
            <value>luoxn28</value>
            <value>luoxn29</value>
            <value>luoxn30</value>
        </list>
    </property>
    <property name="set">
        <set>
            <value>luoxn28</value>
            <value>luoxn29</value>
            <value>luoxn30</value>
        </set>
    </property>
    <property name="map">
        <map>
            <entry key="str1" value="luoxn28"/>
            <entry key="str2"><value>luoxn29</value></entry>
            <entry key="str3"><value>luoxn30</value></entry>
        </map>
    </property>
</bean>

Bean的作用域

Spring最初提供ean的两种scope类型:singleton和prototype,在发布2.0之后,新增了request、session和global session类型,不过这3种新增的只能用在Web应用中。可以通过bean属性scope来指定bean的scope类型,如果是singleton类型的话,在用户获取该bean之后,容器还是会接管该bean的生命周期;如果是prototype的话,在用户获取该bean之后,容器就不接管该bean了,也就是容器每次会创建一个新的bean对象返回给用户。

<!-- Hello对象每次获取都会新建 -->
<bean id="hello" class="com.luoxn28.Hello" scope="prototype">
    <property name="msg" value="luoxn28"/>
</bean>

通过静态方法创建bean

调用静态工厂方法创建 Bean是将对象创建的过程封装到静态方法中,当用户需要对象时,只需要简单地调用静态方法,而不同关心创建对象的细节。要声明通过静态方法创建的 Bean, 需要在 Bean 的 class 属性里指定拥有该工厂的方法的类, 同时在 factory-method 属性里指定工厂方法的名称. 最后, 使用 <constrctor-arg> 元素为该方法传递方法参数。

public static Hello createHello() {
    return new Hello();
}

<bean id="hello" class="com.luoxn28.Hello" factory-method="createHello">
</bean>

BeanFactory

Spring 中有两种类型的 Bean, 一种是普通Bean,另一种是工厂Bean,即FactoryBean。工厂 Bean 跟普通Bean不同,,其返回的对象不是指定类的一个实例,其返回的是该工厂 Bean 的 getObject 方法所返回的对象
FactoryBean接口源码如下所示:

public interface FactoryBean<T> {
    // 返回的实例
    T getObject() throws Exception;
    // 返回的类型
    Class<?> getObjectType();
    // 是否为单例
    boolean isSingleton();
}

BeanFactory使用示例:

public class Hello {
    private String name;
    private int age;
    // set/get方法
}

public class HelloBeanFactory implements FactoryBean<Hello> {
    @Override
    public Hello getObject() throws Exception {
        Hello hello = new Hello();

        hello.setName("luoxn28");
        hello.setAge(23);
        return hello;
    }

    @Override
    public Class<?> getObjectType() {
        return Hello.class;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}

然后在applicationContext.xml中配置如下,就可以获取Hello类实例了。

<bean id="helloBean" class="com.luoxn28.hello.HelloBeanFactory">
</bean>

public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    Hello hello = context.getBean("helloBean", Hello.class);
    System.out.println(hello);
}

参考资料:

  1. Spring的IoC容器
  2. 《Spring揭秘》IOC章节
上一篇下一篇

猜你喜欢

热点阅读