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(); }

運行結果:

相關文章
相關標籤/搜索