Spring之Core模塊

n672 9年前發布 | 15K 次閱讀 Spring JEE框架

Core模塊主要的功能是實現了控制反轉與依賴注入、Bean配置以及加載。Core模塊中有Beans、BeanFactory、BeanDefinitions、ApplicationContext等概念

BeanFactory

BeanFactory是實例化、配置、管理眾多bean的容器

在Web程序中用戶不需要實例化Beanfactory,Web程序加載的時候會自動實例化BeanFactory,并加載所欲的Beans,將各個Bean設置到Servlet、Struts的Action中或者Hibernate資源中

在Java桌面程序中,需要從BeanFactory中獲取Bean,因此需要實例化BeanFactory,例如,加載ClassPath下的配置文件:

ClassPathResource  res = new ClassPathResource(“applicationContext.xml”);
XmlBeanFactory  factory = new XmlBeanFactory  (res);
Iservice service= factory.getBean(“service”);
……
factory.destroySingletons();

或者使用文件流加載任意位置的配置文件

InputStream  in = new FileInputStream(“C:\\ApplicationContext.xml”);
XmlBeanFactory  factory = new XmlBeanFactory  (in);

或者用ClassPathXmlApplicationContext加載多個配置文件(以字符串形式傳入)

ClassPathXmlApplicationContext  appContext = newClassPathXmlApplicationContext(
new String [] {“applicationContext.xml”,”applicationContext-part2.xml”}
);

BeanFactoryfactory = (BeanFactory) appContext;
//ApplicationContext繼承自BeanFactory接口

配置Bean

工廠模式

如果一個bean不能通過new直接實例化,而是通過工廠類的某個方法創建的,需要把<bean>的class屬性配置為工廠類(或者吧factory-bean屬性配置為工廠類對象)

<bean  id=”examBean” class = “examples.MyBeanFactory”method=”createInstance” />
<--等價于下面的配置-->
<bean  id=”examBean2” factory-bean = “examples.MyBeanFactory”method=”createInstance” />

 

構造函數

如果Bean的構造函數帶有參數,需要指定構造函數的參數

<bean id = “examBean”class=” examples.ExampleBean”>
      <constructor-args><ref bean=”anotherBeanId”/></constructor-args>
      <constructor-args><ref bean=”anotherBeanId2”/></constructor-args>
      <constructor-args><value>1</value></constructor-args>
</bean>

參數又先后順序,要與構造函數參數的順序相同

 

單態模式

Bean可以定義是否為單態模式,在非單態模式下,每次請求該Bean都會生成一個新的對象

像數據源等一般配置為單態模式

<bean id=”exampleBean”class=”examples.ExamleBean” singleton=”false”/>

 

property屬性

destroy-method屬性配置關閉方法,如果有配置,在丟棄Java對象時會調用該方法,某些數據源、SessionFactory對象都需要用destroy-method配置關閉方法

<propertyname=”examProperty” value=”pValue” />

等價于

<propertyname=”examProperty”>
      <value>pValue</value>
</property>

注意:

<propertyname=”password”>

      <value></value>

</property>

會將password設置為””,而不是null,如果想設置為null應該為

<propertyname=”password”>

      <null/>

</property>

 

<ref>屬性

Spring配置文件的Bean之間可以相互引用,引用時用<ref>標簽配合Bean的id屬性使用

也可以使用內部配置

<bean id=”dao” class = ”com.clf.DaoImpl”></bean>
<bean id=”serviceImpl”class=”com.clf. serviceImpl”>
      <property name=”dao”>
             <ref bean=”dao”/>
      </property>
</bean>

等價于內部配置

<property name=”dao”>
      <bean class=” com.clf.DaoImpl”/>
</property>
 

除了使用<ref>的bean屬性,還可以使用local、parent,它們與bean屬性的作用是一樣的,但是,local只能使用本配置文件中的bean,parent只能使用父配置文件中的bean

 

<list>屬性

<property name=”propName”>
      <list>
             <value>String、Integer、Double等類型數據</value>
             <ref bean=”dataSource”/>
      </list>
</property>
 

<set>屬性

<property name=”propName”>
      <set>
             <value>String、Integer、Double等類型數據</value>
             <ref bean=”dataSource”/>
      </set>
</property>
 

<map>屬性

<property name=”propName”>
      <map>
             <entry key=”key1”>
                    <value>String、Integer、Double等類型數據</value>
             </entry>
             <entry key-ref=”key2”>
                    <ref bean=”dataSource”/>
             </entry>
      </map>
</property>

 

<props>屬性

<property name=”propName”>
      <props>
             <prop key=”url”>http://localhost:8080/clf</prop>
             <prop key=”name”>clf</prop>
      </ props >
</property>
 

<destroy-method>和<init-method>屬性

<bean id=”dataSource”class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”>

……

</bean>

Spring在注銷這些資源時會調用close方法

 

有些對象在實例化之后需要執行某些初始化代碼,但是這些代碼不能寫進構造函數,這時候可以把初始化代碼寫進某個方法中,并用<init-method>指定該方法

<bean id=”c”class=”com.clf.SpringExample”  init-method=”init”>

 

depends-on屬性

Spring會默認按照配置文件里的Bean順序地實例化Bean,但是有時候實例化A對象之前需要先實例化后面的B對象,這時候可以使用depends-on屬性強制先實例化B對象

<bean id=”a”clas=”com.clf.A” depends-on=”b”></bean>
<bean id=”b”clas=”com.clf.B” ></bean>
 

<idref>與<ref>的區別

<idref>與<ref>的作用是一樣的,都是配置Java對象的,不同的是,<idref>只有bean與local屬性,沒有parent屬性

Spring加載XML配置文件時,會檢查<idref>配置的Bean在不在,而<ref>只會在第一次調用時才會檢查,換句話說,如果Bean不存在,<idref>在啟動程序時就會拋出錯誤,而<ref>只會在運行中拋出錯誤

 

<autowire>

可以通過Bean的autowire屬性設置自動裝配規則。使用autowire后不需要再用<propertyname=”” value=”” />顯式地設置該Bean的屬性、依賴關系,Spring會根據反射,自動尋找符合條件的屬性,設置到該Bean上

autowire屬性定義的不是需要自動裝配的屬性名,而是自動裝配的規則,一旦配置,所有的屬性都會遵循autowire定義的規則

 

No:即不啟用自動裝配。Autowire默認的值。

byName:通過屬性的名字的方式查找JavaBean依賴的對象并為其注入。比如說類Computer有個屬性printer,指定其autowire屬性為byName后,Spring IoC容器會在配置文件中查找id/name屬性為printer的bean,然后使用Setter方法為其注入。

byType:通過屬性的類型查找JavaBean依賴的對象并為其注入。比如類Computer有個屬性printer,類型為Printer,那么,指定其autowire屬性為byType后,Spring IoC容器會查找Class屬性為Printer的bean,使用Setter方法為其注入。

constructor:通byType一樣,也是通過類型查找依賴對象。與byType的區別在于它不是使用Setter方法注入,而是使用構造子注入。

autodetect:在byType和constructor之間自動的選擇注入方式。

default:由上級標簽<beans>的default-autowire屬性確定。

 

dependency-check

有時候某些Bean的屬性配置有錯誤,這種錯誤在程序啟動的時候不會有任何異常,會一直潛伏到Spring調用該Bean時才會被發現

依賴檢查能夠檢查屬性是否被設置,如果配置了依賴檢查,程序啟動是會進行配置校驗,以便及時地發現錯誤。

但是需要注意的是,依賴檢查是很生硬的,例如設置為object,將會檢查所有的Java對象屬性,只要有一個屬性沒有設置,就會拋出異常

 

no或default:不做任何檢查,默認

simple:僅檢查基本類型、集合屬性

object:僅檢查Java對象屬性

all:檢查所有屬性

Bean的高級特性

BeanNameAware接口幫助Bean知道自己在配置文件中的id

import  org.springframework.beans.factory.BeanNameAware
public class  BeanNameTest implementsBeanNameAware{
      private String beanName;
      //Spring會調用該方法
      public void setBeanName(String beanName){
             this.beanName = beanName;
      }

}
 

BeanFactoryAware接口幫助Bean知道哪個BeanFactory實例化了自己

public interface  BeanFactoryAware{
      void setBeanFactoryAware(BeanFactorybeanFactory) throws BeanException;
}

用法同BeanNameAware

此外還有一下常用的方法

boolean containsBean(String)判定指定名稱的Bean是否存在

Object getBean(String)返回指定名稱,如果沒有該Bean會拋出異常

Object getBean(String,Class)返回指定名稱的Bean,并轉化為指定的類對象

boolean isSingleton(String)判斷指定名稱的Bean是否被配置為單態模式

String [] getAliases(String)返回指定名稱的Bean的別名

 

InitializingBean接口會在Bean實例化后、所有屬性被設置后調用初始化方法。但是使用該接口會與Spring代碼發生耦合,因此不推薦使用,Spring推薦使用init-method配置

public interface InitializingBean{
      public void afterPropertiesSet();  //初始化時調用此方法
}
 

DisposableBean接口會在Bean對象丟棄時調用銷毀方法

public interface DisposableBean{
      public void destroy();  //銷毀時調用此方法
}

屬性覆蓋器

對于一些參數,更實用更簡單的方法是使用properties配置,而不是配置在Spring的配置文件中

PropertyPlaceholderConfigurer允許把XML配置的某些參數配置到properties文件中

<bean id=”dataSource”class=”org.apache.commons.dbcp.BasicDataSource” destroy-method=”close”>
      <property name=”driverClassName” value=”${jdbc.driverClassName}”/>
      <property name=”url” value=”${jdbc.url}”/>
      <property name=”username” value=”${jdbc.username }”/>
      <property name=”password” value=”${jdbc.password }”/>
</bean>

<bean id=”propertyConfigurer”class=”org.springframework.beans.factory.config.PropertyPlaceholderConfigurer”>
      <property name=”loaction” value=”classpath:jdbc.properties”>
</bean>

 

jdbc.properties

jdbc.driverClassName= com.mysql.jdbc.Driver
jdbc.url =jdbc:mysql://localhost:3306/clf?characterEncoding=UTF-8
jdbc.username =clf
jdbc.password =admin

 本文由用戶 n672 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!