spring入门篇2 --- IOC设计思想

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring入门篇2 --- IOC设计思想相关的知识,希望对你有一定的参考价值。

在上一篇中已经大致了解了IOC的设计思想,IOC全拼是Inversion of Control,就是控制反转,以前我们都是自己创建对象,进行实例化,现在交给框架spring来进行控制,以实现高度的解耦。

IOC是设计思想,是Spring的核心,我们必须要掌握,因此通过几个例子,来看看到底是如何实现的,这样就可以有更清晰的认知,所有的demo源码放在了github上,后续学习过程会进行持续的更新,以后不再赘述。

学习这个之前,我们需要了解一下什么是DI,Dependency Injection,依赖注入,什么意思,就是在创建对象实例的时候,同时为这个对象注入他所依赖的属性,说白了就是把bean之间的依赖关系就给spring容器进行管理,在通俗一点就是可以想像是一个赋值的过程。

首先先创建一个类,最近听说有个宠爱的电影,那就来创建一个Dog类,代码很简单

package com.yang;

import java.util.Arrays;

public class Dog {
    private int id;
    private String name;
    private String masterName;
    private String[] loveFood;

    public void createDog() {
        System.out.println("Dog实例要被创建啦");
    }

    public void destroyDog() {
        System.out.println("Dog实例要被销毁啦");

    }

    public Dog() {
        System.out.println("Dog 无参构造函数");

    }

    public Dog(int id, String name, String masterName, String[] loveFood) {
        this.loveFood = loveFood;
        System.out.println("Dog 有参数构造函数");
        this.id = id;
        this.name = name;
        this.masterName = masterName;
    }

    public String getMasterName() {
        return masterName;
    }

    public void setMasterName(String masterName) {
        this.masterName = masterName;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }


    public String[] getLoveFood() {
        return loveFood;
    }

    public void setLoveFood(String[] loveFood) {
        this.loveFood = loveFood;
    }

    @Override
    public String toString() {
        return "Dog{" +
                "id=" + id +
                ", name=‘" + name + ‘‘‘ +
                ", masterName=‘" + masterName + ‘‘‘ +
                ", loveFood=" + Arrays.toString(loveFood) +
                ‘}‘;
    }
}

 

 

接下来看一下applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        注意:现在基本都是用注解代替这个,学习这个,只是为了更好的了解IOC

        id 跟 name 必须是唯一的,我们到时候可以根据id或者name来查找spring为我们创建的实例,name就是别名的意思,可以创建多个别名
        class 就是我们的需要实例化的类是哪个
        scope 就是设置bean对应对象的生成规则,默认是singleton也就是单例模式,prototype也就是使用的时候创建一个新的实例,
            还有request 表示一次请求范围, session一次会话范围
        lazy-init 注意默认值是false,只是对单例起作用,如果为true就是延迟创建,也就是需要的时候在进行创建,这个可以开启debug模式进行确认
        destroy-method 这个是在实例销毁时进行调用,例如数据库连接实例
        init-method 这个是在实例创建之初进行调用
        bean默认进行单行处理的,因此记得自己创建的类中必须有无参构建函数
        bean的注入可以通过
            property调用setXXX方法,
            通过constructor-arg方法,调用构造函数方法,
            p注入,也就是名称空间注入
        对于constructor-arg一般建议index与name一起用,以防止出现歧义,或者自己记混了,最好也把type加上
        针对注入方式
            value只能进行单纯的赋值,也就是基本类型值的注入,
            ref可以赋予对象,
            命名空间对象的注入就是p:属性名-ref
    -->
    <!-- 调用set方法 -->
    <bean id="d1" name="dog1,dog2" class="com.yang.Dog" lazy-init="true" destroy-method="destroyDog"
          init-method="createDog">
        <property name="id" value="1"/>
        <property name="name" value="jack"/>
        <property name="masterName" value="ning"/>
        <property name="loveFood">
            <list>
                <value>shit</value>
                <value>fruit</value>
            </list>
        </property>
    </bean>
    <!-- 调用构造函数 -->
    <bean id="d2" name="dog3" class="com.yang.Dog" scope="prototype" destroy-method="destroyDog"
          init-method="createDog">
        <constructor-arg index="0" value="2" name="id" type="int"/>
        <constructor-arg index="1" value="tom" name="name" type="java.lang.String"/>
        <constructor-arg index="2" value="hong" name="masterName" type="java.lang.String"/>
        <constructor-arg index="3" name="loveFood">
            <list>
                <value>boon</value>
                <value>meat</value>
            </list>
        </constructor-arg>
    </bean>
    <!-- 无参 -->
    <bean id="d3" name="dog4" class="com.yang.Dog"/>
    <bean id="d4" name="dog5" class="com.yang.Dog" p:id="3" p:name="jerry" p:masterName="ning"/>
</beans>

最后我们编写一下测试

package com.yang.test;

import com.yang.Dog;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DogTest {

    @Test
    public void test1() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Dog d1 = context.getBean("d1", Dog.class);
        System.out.println(d1);
        Dog d1Name = context.getBean("dog1", Dog.class);
        System.out.println(d1Name);
        Dog d2 = context.getBean("d2", Dog.class);
        System.out.println(d2);
        Dog d3 = context.getBean("d3", Dog.class);
        System.out.println(d3);
        Dog d4 = context.getBean("d4", Dog.class);
        System.out.println(d4);
        try{
            Thread.sleep(2000);
        }catch (Exception e){
            e.printStackTrace();
        }
        context.close();
    }
}

 

看一下输出结果

Dog 无参构造函数
Dog 无参构造函数
Dog 无参构造函数
Dog实例要被创建啦
Dog{id=1, name=‘jack‘, masterName=‘ning‘, loveFood=[shit, fruit]}
Dog{id=1, name=‘jack‘, masterName=‘ning‘, loveFood=[shit, fruit]}
Dog 有参数构造函数
Dog实例要被创建啦
Dog{id=2, name=‘tom‘, masterName=‘hong‘, loveFood=[boon, meat]}
Dog{id=0, name=‘null‘, masterName=‘null‘, loveFood=null}
Dog{id=3, name=‘jerry‘, masterName=‘ning‘, loveFood=null}

记得在测试程序中让程序停顿一下在手动关闭context。

这就是IOC思想,所有对象的管理交给Spring,我们只需要配置就可以,然后进行调用。

以上是关于spring入门篇2 --- IOC设计思想的主要内容,如果未能解决你的问题,请参考以下文章

Spring入门篇——第2章 Spring IOC容器

《Java从入门到放弃》入门篇:spring中IOC的注入姿势

慕课-《Spring入门篇》学习笔记 专题一 IOC

Spring课程 Spring入门篇 2-2 Spring注入方式

Spring入门系列:篇3——再探IOC

spring入门篇-学习笔记