Spring IoC介紹與Bean的使用

1. 介紹

IoC

  IoC—Inversion of Control,即「控制反轉」,它不是什麼技術,而是一種設計思想。在 Java 開發中, IoC意味着將設計好的對象交給容器控制,而不是傳統的在對象內部直接控制。
  傳統Java程序中,咱們直接在對象內部經過new進行建立對象,是程序去主動建立依賴對象;而IoC是有專門的一個容器來建立這些對象,即由IoC容器來控制對象的建立。反轉則是由容器來幫忙建立及注入依賴對象。
  IoC不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導咱們如何設計出鬆耦合、更優良的程序。傳統應用程序都是由咱們在類內部主動建立依賴對象,從而致使類與類之間高耦合,難於測試;有了IoC容器後,把建立和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,因此對象與對象之間是鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程序的整個體系結構變得很是靈活。java

DI

  DI—Dependency Injection,即「依賴注入」:是組件之間依賴關係由容器在運行期決定,形象的說,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並不是爲軟件系統帶來更多功能,而是爲了提高組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。經過依賴注入機制,咱們只須要經過簡單的配置,而無需任何代碼就可指定目標須要的資源,完成自身的業務邏輯,而不須要關心具體的資源來自何處,由誰實現。
  對於IoC和DI,其實它們是同一個概念的不一樣角度的描述web

IoC容器

  IoC容器就是具備依賴注入功能的容器,IoC容器負責實例化、定位、配置應用程序中的對象及創建這些對象間的依賴。應用程序無需直接在代碼中new相關的對象,應用程序由IoC容器進行組裝。在Spring中BeanFactory是IoC容器的實際表明者。
  在 Spring Ioc 容器的表明就是 org.springframework.beans 包中的BeanFactory 接口, BeanFactory 接口提供了 IoC 容器最基本功能;而org.springframework.context 包下的 ApplicationContext 接口擴展了 BeanFactory ,還提供了與Spring AOP 集成、國際化處理、事件傳播及提供不一樣層次的 context 實現 (如針對 web 應用的 WebApplicationContext )。簡單說, BeanFactory 提供了 IoC 容器最基本功能,而 ApplicationContext 則增長了更多支持企業級功能支持。 ApplicationContext 徹底繼承 BeanFactory ,於是 BeanFactory 所具備的語義也適用於 ApplicationContext。spring

2. 使用

2.1 直接使用,給Bean注入value

  1. 首先建立一個Maven項目,建立方法能夠參考我以前的博客。而後在pom.xml中注入spring相關的包。
  2. 建立一個類Person,再建立一個測試類Main,在resources文件夾中建立一個spring.xml文件。
  3. 運行輸出結果,就能夠把注入的value輸出。

Person.java編程

package com.liu5599.test;

public class Person {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "name: " + name + " age: " + age;
    }
}

Main.javasession

package com.liu5599.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

        Person p = (Person)context.getBean("person");
        System.out.println(p);
    }
}

spring.xmlide

  • 這裏使用了三種方式給Bean注入value,第三種方式須要設置命名空間xmlns:p="http://www.springframework.org/schema/p"。
<?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-3.0.xsd">

    <bean id = "person" class = "com.liu5599.test.Person">
        <property name="name" value="liuyang" />
        <property name="age"  value="21" />
    </bean>

    <!--<bean id = "person" class = "com.liu5599.test.Person">-->
        <!--<property name="name">-->
            <!--<value>liuyang</value>-->
        <!--</property>-->
        <!--<property name="age">-->
            <!--<value>21</value>-->
        <!--</property>-->
    <!--</bean>-->

    <!--<bean id = "person" class = "com.liu5599.test.Person"-->
        <!--p:name = "liuyang" p:age = "21">-->
</beans>

輸出結果:函數

name: liuyang age: 21

2.2 內部嵌套的Bean

接着講述一個Bean中嵌套着另一個Bean。測試

1.第一種方式是在Student中經過ref屬性引用Person的Bean,可是一旦Person被引用到了Student下,也就不會被其餘的Bean引用了。this

2.第二種方式是在Student的Bean中聲明一個內部的Bean。prototype

3.第三種方式是經過構造函數注入。

將測試類進行修改以下:

package com.liu5599.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

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

        Student p = (Student)context.getBean("student");
        System.out.println(p);
    }
}

輸出結果:

Student name: liuyang age: 21

2.3 Bean的做用域

在Spring中,支持以下5種類型的做用域:

  1. singleton — 單例模式,由 IOC 容器返回一個惟一的 bean 實例。
  2. prototype — 原型模式,被請求時,每次返回一個新的 bean 實例。
  3. request — 每一個 HTTP Request 請求返回一個惟一的 Bean 實例。
  4. session — 每一個 HTTP Session 返回一個惟一的 Bean 實例。
  5. globalSession — Http Session 全局 Bean 實例。

默認狀況下,做用域是單例

單例模式與原型模式的區別

單例模式

  • 編寫一個消息類,在Bean中將此類設置爲默認狀況,也就是單例模式。
public class Message {
    private String message;

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }
}

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

        Message m1 = (Message) context.getBean("message");
        m1.setMessage("Message1");
        System.out.println("Message1: " + m1.getMessage());

        Message m2 = (Message)context.getBean("message");
        System.out.println("Message2: " + m2.getMessage());
    }
}

輸出結果:

Message1: Message1
Message2: Message1

原型模式

  • 將Bean的做用域改成prototype。仍是上述測試類,運行。
<bean id = "message" class = "com.liu5599.test.Message" scope="prototype" />

運行結果:

Message1: Message1
Message2: null
  • 第二次輸出爲null,因此證實在原型模式下,每一次請求返回一個新的Bean。

2.4 集合類型的Bean

  這裏主要講述List、Set、Map和Properties四種集合類型。
  Properties類型相似於特殊的Map,不一樣之處是Map的key能夠爲任意類型對象,而Properties類型的key只能是字符串。

1.首先修改Student類,修改以下。

public class Student {
    private List<Object> lists;
    private Set<Object> sets ;
    private Map<Object, Object> maps ;
    private Properties pros;

    public List<Object> getLists() {
        return lists;
    }
    public void setLists(List<Object> lists) {
        this.lists = lists;
    }
    public Set<Object> getSets() {
        return sets;
    }
    public void setSets(Set<Object> sets) {
        this.sets = sets;
    }
    public Map<Object, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<Object, Object> maps) {
        this.maps = maps;
    }
    public Properties getPros() {
        return pros;
    }
    public void setPros(Properties pros) {
        this.pros = pros;
    }

    private Person person;

    public Student() {}

    public Student(Person person) {
        this.person = person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    @Override
    public String toString() {
        return "Student " + person;
    }
}

2.修改spring.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id = "person" class = "com.liu5599.test.Person">
        <property name = "name" value = "liuyang" />
        <property name = "age"  value = "21" />
    </bean>

    <bean id = "student" class="com.liu5599.test.Student">
        <property name = "lists">
            <list>
                <value>1</value>
                <ref bean = "person" />
                <bean class = "com.liu5599.test.Person">
                    <property name = "name" value = "abc" />
                    <property name = "age" value = "20" />
                </bean>
            </list>
        </property>

        <property name="sets">
            <set>
                <value>1</value>
                <ref bean = "person" />
                <bean class = "com.liu5599.test.Person">
                    <property name = "name" value = "abc" />
                    <property name = "age" value = "20" />
                </bean>
            </set>
        </property>

        <property name="maps">
            <map>
                <entry key = "key1" value = "123" />
                <entry key = "key2" value-ref = "person" />
                <entry key = "key3">
                    <bean class = "com.liu5599.test.Person">
                        <property name = "name" value = "abcd" />
                        <property name = "age" value = "19" />
                    </bean>
                </entry>
            </map>
        </property>

        <property name="pros">
            <props>
                <prop key = "name">liuyang</prop>
                <prop key = "age">21</prop>
            </props>
        </property>


        <property name="person">
            <bean class = "com.liu5599.test.Person">
                <property name = "name" value = "liuyang" />
                <property name = "age"  value = "21" />
            </bean>
        </property>
    </bean>

    <bean id = "message" class = "com.liu5599.test.Message" scope="prototype" />
</beans>

3.修改測試類,以下。

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


        Student s = (Student)context.getBean("student");
        System.out.println(s.getLists().toString());
        System.out.println(s.getSets().toString());
        System.out.println(s.getMaps().toString());
        System.out.println(s.getPros().toString());
    }
}

輸出結果:

[1, name: liuyang age: 21, name: abc age: 20]
[1, name: liuyang age: 21, name: abc age: 20]
{key1=123, key2=name: liuyang age: 21, key3=name: abcd age: 19}
{age=21, name=liuyang}

  以上就是Spring Bean的簡單使用方法,可是全都是手動配置的,難以維護,下次我會寫一篇關於註解配置和自動掃描裝配的文章。

相關文章
相關標籤/搜索