Spring(二)Spring Bean管理

Spring工廠類(續)

這裏對上節 Spring工廠類中的BeanFactory和ApplicationContext進行補充

兩者在生成bean實例的時機是不一樣的,前者是在工廠實例化之後,在調用getBean的時候纔會幫我們去創建這個類的實例,而後者是一加載配置文件,就會將配置文件中單例模式生成的類
全部實例化。

一、Spring Bean管理(XML方式)

首先我們要知道三種實例化Bean的方式

  1. 使用類構造器實例化(默認無參數)
  2. 使用靜態工廠方法實例化(簡單工廠模式)
  3. 使用實例工廠方法實例化(工廠方法模式)

接下來我們看看配置文件中一行代碼

<bean id="bean1" class="com.imooc.ioc.demo2.Bean1"/>

bean的配置
id:一般情況下,裝配一個Bean時,通過指定一 個id屬性作爲Bean的名稱,id屬性在IOC容器中必須是唯一的
name: 如果Bean的名稱中含有特殊字符,就需要使用name屬性
class: class用於設置一個類的完全路徑名稱,主要作用是IOC容器生成類的實例

二、Bean的作用域

在這裏插入圖片描述

對於這個作用域我們和Bean的實例化方式我們用一個案例來說明

同樣的我們建立一個Maven項目,引入jar包,這些在上一節有講我們不多說(在下邊貼出引入jar包的代碼),還是得有一個applicationContext.xml的配置文件,我們先進行無參構造器實例化Bean
com.MtLi下新建demo2包,再創建Bean1類和SpringDemo2
Bean1:

package com.MtLi.demo2;

/**
 * Bean的實例化的三種方式:採用無參數的構造方法的方式
 */
public class Bean1 {
    public Bean1(){//構造函數初始化
        System.out.println("Bean1被實例化了...");
    }
}

然後我們配置一下applicationContext.xml
applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

    <!--UserService的創建權交給了Spring-->
    <!--<bean id="userService" class="com.MtLi.demo1.UserServiceImpl">-->
        <!--&lt;!&ndash;設置屬性&ndash;&gt;-->
        <!--<property name="name" value="李四"/>-->
    <!--</bean>-->

    <!--Bean的實例化的三種方式-->
    <!--第一種:無參構造器的方式-->
    <bean id="bean1" class="com.MtLi.demo2.Bean1"/>

在這裏面我們給定該bean的名稱爲bean1,以及對應的類路徑,然後我們在SpringDemo2裏面進行測試
SpringDemo2:

package com.MtLi.demo2;

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

/**
 * 測試Bean的實例化的三種方式
 */
public class SpringDemo2 {
    @Test
    public void demo1(){
        //創建工廠
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通過工廠獲得類的實例:
        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
    }
}

//運行結果
Bean1被實例化了...

看到這個結果,說明調用了構造方法

接下來,我們再來看看第二種方式——使用靜態工廠方法實例化

我們同樣的在com.MtLi.demo2下面新建Bean2,還要新建Bean2Factory類(我們需要對Bean2提供一個靜態工廠,即提供一個靜態方法)
Bean2:

package com.MtLi.demo2;

/**
 * Bean的實例化的三種方式:靜態工廠實例化方式
 */
public class Bean2 {
}
//裏面什麼都不需要加

Bean2Factory:

package com.MtLi.demo2;

/**
 * Bean2的靜態工廠
 */
public class Bean2Factory {
    public static Bean2 creatBean2(){
    //添加靜態方法    
        System.out.println("Bean2Factory的方法已經執行...");
        return new Bean2();
    }
}

然後修改配置文件
applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

    <!--UserService的創建權交給了Spring-->
    <!--<bean id="userService" class="com.MtLi.demo1.UserServiceImpl">-->
        <!--&lt;!&ndash;設置屬性&ndash;&gt;-->
        <!--<property name="name" value="李四"/>-->
    <!--</bean>-->

    <!--Bean的實例化的三種方式-->
    <!--第一種:無參構造器的方式-->
    <!--<bean id="bean1" class="com.MtLi.demo2.Bean1"/>-->
    <!--第二種:靜態工廠的方式-->
    <bean id="bean2" class="com.MtLi.demo2.Bean2Factory" factory-method="creatBean2"/>

這裏路徑是對應的實例類(Bean2的靜態工廠),我們需要指定它的靜態方法,這裏用到"factory-method"標籤,然後我們進行測試
SpringDemo2:

package com.MtLi.demo2;

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

/**
 * 測試Bean的實例化的三種方式
 */
public class SpringDemo2 {
//    @Test
//    public void demo1(){
//        //創建工廠
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        //通過工廠獲得類的實例:
//        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
//    }

    @Test
    public void demo2(){
        //創建工廠
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通過工廠獲得類的實例:
        Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");
    }
}


//運行結果
Bean2Factory的方法已經執行...

接下來是使用實例工廠方法實例化

我們新建Bean3類和Bean3Factory
Bean3:

package com.MtLi.demo2;

/**
 * Bean的實例化三種方式:實例工廠實例化
 */
public class Bean3 {
}
//裏面什麼都不需要加

Bean3Factory:

package com.MtLi.demo2;

/**
 * Bean3的實例工廠
 */
public class Bean3Factory {
    public Bean3 createBean3(){
    //和靜態工廠主要的區別就是方法不是靜態的
        System.out.println("Bean3Factory的方法已經執行...");
        return new Bean3();
    }
}

然後修改配置文件
applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

    <!--UserService的創建權交給了Spring-->
    <!--<bean id="userService" class="com.MtLi.demo1.UserServiceImpl">-->
        <!--&lt;!&ndash;設置屬性&ndash;&gt;-->
        <!--<property name="name" value="李四"/>-->
    <!--</bean>-->

    <!--Bean的實例化的三種方式-->
    <!--第一種:無參構造器的方式-->
    <!--<bean id="bean1" class="com.MtLi.demo2.Bean1"/>-->
    <!--第二種:靜態工廠的方式-->
    <!--<bean id="bean2" class="com.MtLi.demo2.Bean2Factory" factory-method="creatBean2"/>-->
    <!--第三種:實例工廠的方式-->
    <!--非靜態需要先寫工廠的實例-->
    <bean id="bean3Factory" class="com.MtLi.demo2.Bean3Factory"/>
    <bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>

非靜態和靜態的配置不相同,靜態可以直接指定方法,指定工廠類路徑,但是非靜態需要先有工廠的實例,然後再配置方法,需要指定工廠bean爲工廠實例的bean名稱(指明該方法的屬向)
然後我們進行測試
SpringDemo2:

package com.MtLi.demo2;

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

/**
 * 測試Bean的實例化的三種方式
 */
public class SpringDemo2 {
//    @Test
//    public void demo1(){
//        //創建工廠
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        //通過工廠獲得類的實例:
//        Bean1 bean1 = (Bean1)applicationContext.getBean("bean1");
//    }

//    @Test
//    public void demo2(){
//        //創建工廠
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        //通過工廠獲得類的實例:
//        Bean2 bean2 = (Bean2)applicationContext.getBean("bean2");
//    }

    @Test
    public void demo3(){
        //創建工廠
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //通過工廠獲得類的實例:
        Bean3 bean3 = (Bean3)applicationContext.getBean("bean3");
    }
}


//運行結果
Bean3Factory的方法已經執行...

關於Bean的作用域測試

先測試singleton功能

我們還是在com.MtLi裏面新建一個demo3的包,我們新建一個Person類並進行配置
Person:

package com.MtLi.demo3;

public class Person {
}

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

    <!--UserService的創建權交給了Spring-->
    <!--<bean id="userService" class="com.MtLi.demo1.UserServiceImpl">-->
        <!--&lt;!&ndash;設置屬性&ndash;&gt;-->
        <!--<property name="name" value="李四"/>-->
    <!--</bean>-->

    <!--Bean的實例化的三種方式-->
    <!--第一種:無參構造器的方式-->
    <!--<bean id="bean1" class="com.MtLi.demo2.Bean1"/>-->
    <!--第二種:靜態工廠的方式-->
    <!--<bean id="bean2" class="com.MtLi.demo2.Bean2Factory" factory-method="creatBean2"/>-->
    <!--第三種:實例工廠的方式-->
    <!--非靜態需要先寫工廠的實例-->
    <!--<bean id="bean3Factory" class="com.MtLi.demo2.Bean3Factory"/>-->
    <!--<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>-->

    <!--Bean的作用範圍-->
    <bean id="person" class="com.MtLi.demo3.Person"/>

這裏的scope爲空,默認爲singleton,即單例模式,我們測試一下
SpringDemo3:

package com.MtLi.demo3;

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

/**
 * Bean的作用範圍的測試
 */
public class SpringDemo3 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person1 =(Person)applicationContext.getBean("person");
        Person person2 =(Person)applicationContext.getBean("person");

        System.out.println(person1);
        System.out.println(person2);
        }
}

//運行結果
com.MtLi.demo3.Person@670b40af
com.MtLi.demo3.Person@670b40af

在這裏我們我們獲取兩個對象,打印這兩個對象的地址,看兩個的地址是否一樣,很顯然是一樣的,這兩個實際上是一個對象,這就是singleton單例模式;另一個比較重要的作用域是prototype,下面我們進行測試
applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

    <!--UserService的創建權交給了Spring-->
    <!--<bean id="userService" class="com.MtLi.demo1.UserServiceImpl">-->
        <!--&lt;!&ndash;設置屬性&ndash;&gt;-->
        <!--<property name="name" value="李四"/>-->
    <!--</bean>-->

    <!--Bean的實例化的三種方式-->
    <!--第一種:無參構造器的方式-->
    <!--<bean id="bean1" class="com.MtLi.demo2.Bean1"/>-->
    <!--第二種:靜態工廠的方式-->
    <!--<bean id="bean2" class="com.MtLi.demo2.Bean2Factory" factory-method="creatBean2"/>-->
    <!--第三種:實例工廠的方式-->
    <!--非靜態需要先寫工廠的實例-->
    <!--<bean id="bean3Factory" class="com.MtLi.demo2.Bean3Factory"/>-->
    <!--<bean id="bean3" factory-bean="bean3Factory" factory-method="createBean3"/>-->

    <!--Bean的作用範圍-->
    <bean id="person" class="com.MtLi.demo3.Person" scope="prototype"/>

這裏我們只需要加一個scope=“prototype”,然後運行SpringDemo3中的demo1,運行結果如下:

com.MtLi.demo3.Person@cb51256
com.MtLi.demo3.Person@59906517

這就是多實例模式
注意:如果出現警告,我們可以在resources下面引入log4j.properties文件
log4j.properties:

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c\:mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=info, stdout

三、Spring的生命週期

  1. Spring在初始化bean和銷燬bean時,有時需要做一些處理工作,因此Spring可以在創建bean和拆卸拆卸bean時,調用bean的兩個生命週期方法。配置如下:
<bean id="xxx" class="xxxx" init-method="init" destroy-method="destroy"/>

當bean被載入到容器中時調用init方法,當bean從容器中刪除的時候調用destroy方法
注意:destroy只對scope="singleton"即單例模式有效,web容器會自動調用這兩個方法,但是main方法或者做測試用例時需要手動調用

2.Spring容器中Bean的生命週期

在這裏插入圖片描述
根據以上這個圖,我們可以分析一下流程:
第一步:對象實例化
第二步:設置屬性,比如張三,他是男的,則他有性別這個屬性,爲男
第三步:如果 Bean 實現 BeanNameAware 執行 setBeanName,即設置bean的名稱
第四步:如果 Bean 實現 BeanFacotryAware 或者 ApplicationContextAware 設置工廠 setBeanFactory 或者上下文對象 setApplicationContext,即瞭解工廠信息
第五步:如果存在類實現 BeanPostProcessor,執行 postProcessBeforeInitialization,即初始化前方法
第六步:如果 Bean 實現 InitializingBean執行 afterPropertiesSet,即屬性設置以後
第七步:調用 指定初始化方法 init
第八步:如果存在類實現 BeanPostProcessor,執行 postProcessAfterInitialization
第九步:執行業務處理
第十步:如果 Bean 實現 DisposableBean ,執行 destroy,調用 bean的 destroy-method=“customerDestroy”> 指定銷燬方法 customerDestroy

四、Spring的屬性注入

對於類成員變量,注入方式有三種:
——構造函數注入
——屬性setter方法注入

——接口注入
Spring支持前兩種屬性注入

1、構造方法注入

通過構造方法注入Bean的屬性值或依賴的對象,它保證了Bean實例在實例化後就可以使用。構造器諸如在 < constructor-arg> 元素裏聲明的屬性
下面,我們在com.MtLi中新建包demo4,在裏面新建一個類User
User:

package com.MtLi.demo4;

public class User {
   private String name;
   private Integer age;

   public User(String name,Integer age){//構造器初始化
       this.name = name;
       this.age = age;
   }

   @Override
   public String toString() {//進行打印
       return "User{" +
               "name='" + name + '\'' +
               ", age=" + age +
               '}';
   }
}

我們把配置文件applicationContext.xml之前的全部註釋(避免佔大量篇幅,下面不再顯示),在配置文件中,注入屬性
applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

  
    <!--Bean的構造方法的屬性注入=============-->
    <bean id="user" class="com.MtLi.demo4.User">
        <constructor-arg name="name" value="張三"/>
        <constructor-arg name="age" value="23"/>
    </bean>

然後我們進行測試,新建一個測試類SpringDemo4
SpringDemo4:

package com.MtLi.demo4;

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

public class SpringDemo4 {

    @Test
    /**
     * 測試Bean的構造方法的屬性注入
     */
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = (User)applicationContext.getBean("user");
        System.out.println(user);
    }
}

//測試結果
User{name='張三', age=23}
2、setter方法注入

在Spring配置文件中,通過 < property> 設置注入的屬性,下面,新建一個類Person,在裏面先set名字和年齡
Person:

package com.MtLi.demo4;

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

   public String getName() {
       return name;
   }

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

   public Integer getAge() {
       return age;
   }

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

   @Override
   public String toString() {
       return "Person{" +
               "name='" + name + '\'' +
               ", age=" + age +       
               '}';
   }
}

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">

  
    <!--Bean的set方法的屬性注入=============-->
    <bean id="person" class="com.MtLi.demo4.Person">
            <property name="name" value="李四"/>
            <property name="age" value="24"/>
    </bean>

上邊同樣是配置屬性,然後我們進行測試
SpringDemo4:

package com.MtLi.demo4;

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

public class SpringDemo4 {

//    @Test
//    /**
//     * 測試Bean的構造方法的屬性注入
//     */
//    public void demo1(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        User user = (User)applicationContext.getBean("user");
//        System.out.println(user);
//    }

    @Test
    /**
     * 測試Bean的set方法的屬性注入
     */
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        Person person = (Person) applicationContext.getBean("person");
        System.out.println(person);
    }
}
//測試結果
Person{name='李四', age=24}

當然,我們也可以有附加屬性,比如,新建一個Cat類,然後在Person類裏面加一句private Cat cat;,同樣的,需要給他加set、get、toString方法,在配置文件裏面加上 <property name=“cat” ref=“cat”/ >,這句是加在person bean裏面,對於Cat我們同樣需要配置bean,如:

<bean id="cat" class="com.MtLidemo4.Cat">
     <property name="name" value="ketty"/>
</bean>

對於添加在person bean中的一句中,ref代表的是引入其他bean對象

SpEl注入

SpEL:
—— spring expression language,spring表達式語言,對依賴注入進行簡化
—— 語法:#(表達式)
—— < bean id="" value="#(表達式)">,有如下形式:
#(‘hello’):使用字符串
#{topicId3}:使用另外一個bean
#{topicId.content.toUpperCase()}:使用指定屬性,並使用方法
#{T(java.lang.Math).PI):使用靜態字段或方法

例如:

    <bean id="category" class="com.MtLi.demo4.Category">
        <property name="name" value="#{'服裝'}"/>
    </bean>
複雜屬性的注入

複雜屬性注入分爲:
—— 數組類型
—— List集合類型
—— Set集合類型
—— Map集合類型
—— Properties類型

我們新建demo5,新建一個CollectionBean
CollectionBean:

package com.MtLi.demo5;

import java.util.*;

public class CollectionBean {

    private String[] arrs;//數組類型

    private List list;//List集合類型

    private Set set;//Set集合類型

    private Map<String,Integer> map;//Map集合類型

    private Properties properties;//屬性類型

    public String[] getArrs() {
        return arrs;
    }

    public void setArrs(String[] arrs) {
        this.arrs = arrs;
    }

    public List getList() {
        return list;
    }

    public void setList(List list) {
        this.list = list;
    }

    public Set getSet() {
        return set;
    }

    public void setSet(Set set) {
        this.set = set;
    }

    public Map<String, Integer> getMap() {
        return map;
    }

    public void setMap(Map<String, Integer> map) {
        this.map = map;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    @Override
    public String toString() {
        return "CollectionBean{" +
                "arrs=" + Arrays.toString(arrs) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                ", properties=" + properties +
                '}';
    }
}

applicationContext.xml配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       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.xsd">
<!--集合類型的屬性注入-->
    <bean id="collectionBean" class="com.MtLi.demo5.CollectionBean">
        <!--數組類型-->
        <property name="arrs">
            <list>
                <value>aaa</value>
                <value>bbb</value>
                <value>ccc</value>
            </list>
        </property>
        <!--List類型的屬性注入-->
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
                <value>333</value>
            </list>
        </property>
        <!--Set集合的屬性注入-->
        <property name="set">
            <set>
                <value>ddd</value>
                <value>eee</value>
                <value>fff</value>
            </set>
        </property>
        <!--Map集合的屬性注入-->
        <property name="map">
            <map>
                <entry key="aaa" value="111"/>
                <entry key="bbb" value="222"/>
                <entry key="ccc" value="333"/>
            </map>
        </property>
        <!--Properties的屬性注入-->
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">root</prop>
            </props>
        </property>
    </bean>
</beans>```

數組類型和List類型配置bean時,子標籤都是< list>< value>< /value>< /list>
Set類型則是< set>< value>< /value>< /set>
Map類型是< map>< entry key="" value="" />< /map>
Properties類型是< props>< prop key=“XXXX”>XXX< /prop>< /props>
然後我們進行測試
SpringDemo5:

package com.MtLi.demo5;

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

public class SpringDemo5 {
    @Test
    public void demo1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        CollectionBean collectionBean = (CollectionBean)applicationContext.getBean("collectionBean");

        System.out.println(collectionBean);
    }
}

//運行結果
CollectionBean{arrs=[aaa, bbb, ccc], list=[111, 222, 333], set=[ddd, eee, fff], map={aaa=111, bbb=222, ccc=333}, properties={password=root, username=root}}

五、Spring Bean管理(註解方式)

以上都是XML方式,下面我們來說說Spring Bean管理的註解方式,註解方式在企業開發中用的比較多,原因是在開發中比XML方便一些。我們新建一個項目spring_ioc_annotation,並且建立包com.MtLi.demo1我們先在pom.xml中引入jar包:

 <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-expression</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.2.4.RELEASE</version>
    </dependency>
  </dependencies>

然後新建名爲applicationContext.xml的配置文件,爲了防止出現警告,我們還需要引入log4j文件(上邊已經給出)
請注意,新建的配置文件只有beans的約束,我們還需要一個context的約束(可以自行搜索),然後我們便可以開啓註解掃描(其作用是去每個包下邊找是否有註解),下邊我們直接貼出:

<?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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
      http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
      
  <!--開啓註解掃描=======================-->
  <context:component-scan base-package="com.MtLi。demo1"/>
</beans>   

然後我們新建一個UserService
UserService:

package com.MtLi.demo1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Spring的Bean管理的註解方式
 * *傳統方式需要去XML中配置<bean id="class="></bean>
 */
 @Component("userService")
public class UserService {
    public String sayHello(String name){
        return "Hello"+name;
    }
 }

寫一個測試
SpringDemo1:

package com.MtLi.demo1;

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

public class SpringDemo1 {
   @Test
   public void demo1(){
       ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

       UserService userService = (UserService)applicationContext.getBean("userService");

       String s= userService.sayHello("張三");

       System.out.println(s);
   }
}

//運行結果
Hello張三

該例中用到的 @Component 用來描述Spring框架中的Bean,使得配置文件中的註解掃描可以掃描到
除了 @Component之外,Spring提供了三個功能基本和 @Component等效的註解:
—— @Repository 用於對DAO實現類進行標註
—— @Service 用於對Service實現類進行標註
—— @Controller 用於對Controller實現類進行標註
這三個註解是爲了讓標註類本身的用途清晰

Spring的屬性注入—註解方式

在這裏我們不需要set、get方法就可以對屬性注入值
UserService:

package com.MtLi.demo1;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * Spring的Bean管理的註解方式
 * *傳統方式需要去XML中配置<bean id="class="></bean>
 */
//@Component("userService")
    @Service("userService")
public class UserService {
    @Value("米飯")
    private String somthing;

    public String sayHello(String name) {
        return "Hello" + name;
    }

    public void eat() {
        System.out.println("eat" + somthing);
    }
}

這裏我們將@Component換成@Service(bean註解),然後我們要爲something注入值,可以直接在上邊@Value(" ")設值,下面測試一下
SpringDemo1:

package com.MtLi.demo1;

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

public class SpringDemo1 {
//    @Test
//    public void demo1(){
//        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//
//        UserService userService = (UserService)applicationContext.getBean("userService");
//
//        String s= userService.sayHello("張三");
//
//        System.out.println(s);
//    }

    @Test
    public void demo2(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");

        UserService userService = (UserService)applicationContext.getBean("userService");

        userService.eat();
    }
}

//運行結果
eat米飯

以上是一個簡單的屬性注入,但如果我們要引入Dao的對象呢(後續更新)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章