Spring框架學習03——Spring Bean 的詳解

一、Bean 的配置

Spring能夠看作一個大型工廠,用於生產和管理Spring容器中的Bean,Spring框架支持XML和Properties兩種格式的配置文件,在實際開發中經常使用XML格式的配置文件。
XML配置文件的跟標籤是<beans>,<beans>中包含了多個<bean>子元素,每一個<bean>元素定義一個Bean,並描述Bean如何被裝配到Spring容器中。
<bean>元素的經常使用屬性及其子元素說明以下:java

  • id屬性:Bean在BeanFactory中的惟一標識,在代碼中經過BeanFactory獲取Bean實例時須要以此做爲索引名稱;
  • name屬性:和id屬性的用法相似,該屬性的值中能夠包含特殊字符;
  • class屬性:Bean的具體實現類,使用類的名(例如 dao.TestDIDaoImpl);
  • scope屬性:指定Bean實例的做用域;
  • <constructor-arg>子元素:<bean>元素的子元素,使用構造方法注入,指定構造方法的參數。該元素的index屬性指定參數的序號,ref屬性指定對BeanFactory中其餘Bean的引用關係,type屬性指定參數類型,value屬性指定參數的常量值;
  • <property>子元素:<bean>元素的子元素,用於設置一個屬性。該元素的name屬性指定Bean實例中相應的屬性名稱,value屬性指定Bean的屬性值,ref屬性指定屬性對BeanFactory中其餘Bean的引用關係;
  • <list>子元素:<property>元素的子元素,用於封裝List或數組類型的依賴注入;
  • <map>子元素:<property>元素的子元素,用於封裝Map類型的依賴注入;
  • <set>子元素:<property>元素的子元素,用於封裝Set類型的依賴注入;
  • <entry>子元素:<map>元素的子元素,用於設置一個鍵值對;

二、Bean 的實例化

Spring框架實例化Bean有3種方法,即構造方法實例化、靜態工廠實例化、實例工廠實例化。web

2.一、構造方法實例化

在Spring框架中,Spring容器能夠調用Bean對應類中的無參構造方法來實例化Bean,這種方法稱爲構造方法實例化。
在src目錄下建立entity包,並建立BeanClass類,代碼以下:spring

package entity;

public class BeanClass {
    public BeanClass() {
        System.out.println("構造方法實例化Bean...");
    }
}

在applicationContext.xml中配置Bean數組

<?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.xsd">

    <!--構造方法實例化Bean-->
    <bean id="beanClass" class="entity.BeanClass"></bean>
</beans>

   測試代碼websocket

@Test
public void demo(){
    //初始化Spring容器ApplicationContext,加載配置文件
    ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    BeanClass beanClass = (BeanClass) application.getBean("beanClass");
}

運行結果session

2.二、靜態工廠實例化

建立BeanClass類,代碼以下:app

package entity;

public class BeanClass {
    public BeanClass(String str){
        System.out.println(str);
    }
}

建立靜態工廠類,代碼以下:框架

package entity;

public class BeanStaticFactory {
    public static BeanClass createBean(){
        return new BeanClass("靜態工廠實例化Bean...");
    }
}

在applicationContext.xml配置靜態工廠Beansocket

<?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.xsd">

    <!--靜態工廠實例化Bean,factory-method屬性指定靜態方法-->
    <bean id="beanStaticFactory" class="entity.BeanStaticFactory" factory-method="createBean"></bean>
</beans>

測試代碼ide

@Test
public void demo(){
    //初始化Spring容器ApplicationContext,加載配置文件
    ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    BeanClass beanClass = (BeanClass) application.getBean("beanStaticFactory");
}

運行結果

2.三、實例工廠實例化

建立BeanClass類,代碼以下:

package entity;

public class BeanClass {
   /* public BeanClass() {
        System.out.println("構造方法實例化Bean...");
    }*/
    public BeanClass(String str){
        System.out.println(str);
    }
}

建立工廠類,代碼以下:

package entity;

public class BeanFactory {
    public BeanClass createBean(){
        return new BeanClass("實例工廠實例化Bean...");
    }
}

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

    <!--配置工廠-->
    <bean id="beanFactory" class="entity.BeanFactory"></bean>
    <!--實例工廠實例化Bean,
        factory-bean屬性指定配置工廠,
        factory-method屬性指定實例化Bean的方法
        -->
    <bean id="instanceBean" factory-bean="beanFactory" factory-method="createBean"></bean>

</beans>

測試代碼

@Test
public void demo(){
    //初始化Spring容器ApplicationContext,加載配置文件
    ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    BeanClass beanClass = (BeanClass) application.getBean("instanceBean");
}

運行結果

三、Bean 的做用域

在Spring中不只能夠完成Bean的實例化,還能夠爲Bean指定做用域,具體用法是在<bean>元素上配置scope屬性,屬性的值有如下幾種:

  • sigleton:默認的做用域,使用singleton定義的Bean在Spring容器中只有一個Bean實例,即單例模式;
  • prototype:Spring容器每次獲取prototype定義的Bean,容器都將建立一個新的Bean實例,即多例模式;
  • request:在一次HTTP請求中容器將返回一個Bean實例,不一樣的HTTP請求返回不一樣的Bean實例。僅在Web Spring應用程序上下文中使用;
  • session:在一個HTTP Session中,容器將返回同一個Bean實例。僅在Web Spring應用程序上下文中使用;
  • application:爲每一個ServletContext對象建立一個實例,即同一個應用共享一個Bean實例。僅在Web Spring應用程序上下文中使用;
  • websocket:爲每一個WebSocket對象建立一個Bean實例。僅在Web Spring應用程序上下文中使用;

四、Bean 的生命週期

Spring初始化bean或銷燬bean時,有時須要作一些處理工做,所以Spring能夠在建立和銷燬bean的時候調用bean的兩個生命週期方法,代碼示例以下:
建立BeanClass類

package entity;

public class BeanClass {
   public void initMyself(){
       System.out.println("自定義初始化方法執行...");
   }
   public void destoryMyself(){
       System.out.println("自定義銷燬方法執行...");
   }
}

在applicationContext.xml中配置Bean

<?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.xsd">

   <!--配置bean,
       使用init-method屬性指定初始化方法,
       使用destroy-method屬性指定銷燬方法
       -->
    <bean id="beanClass" class="entity.BeanClass" init-method="initMyself" destroy-method="destoryMyself"></bean>

</beans>

測試代碼

@Test
public void demo(){
    //爲了方便演示銷燬方法的執行,使用ClassPathXmlApplicationContext
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    BeanClass beanClass = (BeanClass) ctx.getBean("beanClass");
    System.out.println("獲取beanClass對象"+beanClass);
    ctx.close();//關閉容器,銷燬Bean對象

}

運行結果

 

 

五、Bean的裝配方式

5.一、基於XML配置的裝配

建立BeanClass實體類

public class BeanClass {
    private String[] arrs;//數組類型
    private List<String> list;//List集合類型
    private Set<String> set;//Set集合類型
    private Map<String,Integer> map;//Map集合類型
    private Properties prop;//屬性類型

    //getter和setter方法
    //toString()方法

}

在applicationContext.xml中配置Bean

<?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.xsd">

    <!--集合類型屬性注入-->
    <bean id="beanClass" class="entity.BeanClass">
        <!--數組類型-->
        <property name="arrs">
            <list>
                <value>aa</value>
                <value>bb</value>
            </list>
        </property>
        <!--List集合-->
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
            </list>
        </property>
        <!--Set集合-->
        <property name="set">
            <set>
                <value>aaa</value>
                <value>bbb</value>
            </set>
        </property>
        <!--Map集合-->
        <property name="map">
            <map>
                <entry key="aa" value="11"></entry>
                <entry key="bb" value="22"></entry>
            </map>
        </property>
        <!--Properties屬性-->
        <property name="prop">
            <props>
                <prop key="aa">11</prop>
                <prop key="bb">22</prop>
            </props>
        </property>
    </bean>

</beans>

測試代碼

@Test
public void demo(){
    //初始化Spring容器ApplicationContext,加載配置文件
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    BeanClass beanClass = (BeanClass) ctx.getBean("beanClass");
    System.out.println(beanClass);
}

運行結果

 

5.二、基於註解的裝配

在Spring框架中定義了一系列的註解,下面介紹幾個經常使用註解:

  • @Component:該註解是一個泛化的概念,僅僅表示一個組件對象(Bean),能夠做用在任何層次上;
  • @Repository:該註解用於將數據訪問層(DAO)的類標識爲Bean,即註解數據訪問層Bean,其功能與@Component相同;
  • @Service:該註解用於標註一個業務邏輯註解類(Service層),其功能與@Component相同;
  • @Controller:該註解用於標註一個控制器組件類(Spring MVC的Controller),其功能與@Component相同;
  • @Autowired:該註解能夠對類成員變量、方法及構造方法進行標註,完成自動裝配的工做。經過使用@Autowired來消除setter和getter方法。默認按照Bean的類型進行裝配;
  • @Resource:該註解與@Autowired的功能同樣,區別在於該註解默認是按照名稱來裝配注入的,只有當找不到與名稱匹配的Bean時纔會按照類型來裝配注入;@Autowired默認按照Bean的類型進行裝配,若是想按照名稱來裝配注入,則須要和@Qualifier一塊兒使用。@Resource註解有兩個屬性,name屬性指定Bean實例名稱,type屬性指定Bean類型;
  • @Qualifier:該註解與@Autowired註解配合使用。當@Autowired註解須要按照名稱來裝配注入時須要和該註解一塊兒使用,Bean的實例名稱由@Qualifier註解的參數指定;

在上面幾個註解中,雖然@Repository、@Service、@Controller等註解的功能與@Component註解相同,但爲了類的標註層次化更加清晰,在實際開發中推薦使用如下方式進行配置:

  • @Repository標註數據訪問層(DAO層);
  • @Service標註業務邏輯層(Service層);
  • @Controller標註控制層;

代碼示例以下:

(1)建立Dao層

建立dao包,並建立TestDao接口和接口實現類TestDaoImpl,並將實現類TestDaoImpl使用@Repository註解標註爲數據訪問層。
TestDao接口,代碼以下:

package dao;

public interface TestDao {
    public void save();
}

TestDaoImpl實現類,代碼以下:

package dao;

import org.springframework.stereotype.Repository;

/*如何在Service層中使用@Resource(name="testDao"),
  @Repository("testDao")中的testDao不能省略
*/
@Repository("testDao")
public class TestDaoImpl implements TestDao {
    @Override
    public void save() {
        System.out.println("testDao save");
    }
}

(2)建立Service層

建立service包,並建立TestService接口和接口實現類TestServiceImpl,並將實現類TestServiceImpl使用@Service註解標註爲業務邏輯層。
TestService接口,代碼以下:

package service;

public interface TestService {
    public void save();
}

TestServiceImpl接口實現類,代碼以下:

package service;

import dao.TestDao;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

@Service("testService")
public class TestServiceImpl implements TestService {

    @Resource(name = "testDao")
    private TestDao testDao;

    @Override
    public void save() {
        testDao.save();
        System.out.println("testService save");
    }
}

(3)建立Controller層

建立controller包,並建立TestController類,將TestController類使用@Controller註解標註爲控制器層。
TestController類,代碼以下:

package controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import service.TestService;

@Controller
public class TestController {

    @Autowired
    private TestService testService;

    public void save(){
        testService.save();
        System.out.println("testController save");
    }
}

(4)配置註解

在applicationContext.xml中添加context約束,並配置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命名空間,經過Spring掃描指定包-->
    <context:component-scan base-package="dao"></context:component-scan>
    <context:component-scan base-package="service"></context:component-scan>
    <context:component-scan base-package="controller"></context:component-scan>

</beans>

(5)建立測試類

測試方法,代碼以下:

@Test
public void demo(){
    //初始化Spring容器ApplicationContext,加載配置文件
    ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    //經過容器獲取實例
    TestController testCon = (TestController) ctx.getBean("testController");
    testCon.save();
}

運行結果:

相關文章
相關標籤/搜索