Spring回顧一

Spring回顧一

Spring是一個開源的控制反轉(Inversion of Control, IoC)和麪向切面的(AOP, Aspect-Oriented Programming)的容器框架,它的主要目的是簡化企業的開發。

所謂控制反轉就是應用本身不負責依賴對象的創建及維護,依賴對象的創建及維護是由外部容器負責的,這樣控制權就由應用轉移到了外部容器,控制權的轉移就是所謂反轉

所謂依賴注入(Dependency Injection)就是指:在運行時,由外部容器動態地將依賴對象注入到組件中

Spring的好處:

減低組件之間的耦合度,實現軟件各層之間的解耦

可以使用Spring提供的衆多服務,如:事務管理器,消息服務等等。

容器提供單例模式的支持

容器提供了AOP技術

容器提供了衆多的輔助類,使用這些類能夠加快應用的開發

Spring對於主流的應用框架提供了集成的支持

對於spring容器,提供了很多的服務,但這些服務不是默認爲應用打開的。如果提高服務較少則認爲是輕量級的,否則則認爲是重量級的。

spring用到的核心jar文件有兩個:

dist/spring.jar

lib/jakarta-commons/commons-logging.jar

如果使用了切面編程(AOP),還需要下列的jar文件

lib/aspectj/aspectjweaver.jaraspectjrt.jar

lib/cglig/cglib-nodep-2.1-3.jar

如果使用了JSP-250中的註解,

@Resource/@PostConstruct/@PreDestory,還需要下列jar文件

lib/j2ee/common-annotations.jar.

 

實例化Spring容器常用的兩種方式:

方法一:

類路徑下尋找配置文件來實例化容器

ApplicationContext ctx =

new ClassPathXmlApplicationContext(new String[]{“bean.xml”});

方法二:

文件系統路徑下尋找配置文件實例化容器

ApplicationContext ctx =

new FileSystemXmlApplicationContext(new String[]{“d:/beans.xml”});

編寫spring配置文件時不出現幫助信息

由於springschema文件位於網絡上,如果機器不能連接到網絡上,那麼在編寫配置信息時候無法出現提示信息,解決辦法有兩種:

1.     讓機器上網eclipse會自動從網絡上下載schema文件並緩存到本地硬盤上

2.     手動添加schema文件,方法如下:

windows->preferences->myeclipse->files and editors ->xml->xmllocation ”add”,在出現的窗口中的Key Type中選擇URL,location中選擇”File System”,然後在spring解壓目錄的dist/resources目錄中選擇spring-beans-2.5.xsd,回到設置窗口的時候不要急着關閉窗口,應把窗口中的Key Type改爲Schema location,Key

改爲http://www.springframework.org/schema/beans/srping-beans

-2.5.xsd.

<beanid屬性和name屬性,name屬性可以包含特殊字符例如:”/sd/

 

三種實例化bean的方式:

1.     使用類構造器實例化

<bean id=”orderService” class=”cn.itcast.OrderServiceBean”>

2.     使用靜態工廠的方法實例化

<bean id=”personService” class=”cn.itcast.service.OrderFactory” factory-method=”createOrder” />

3.     使用實例化工廠的方法實例化

<bean id=”personServiceFactory” class=”cn.itcast.service.OrderFactory” />

<bean id=”personSercie” factory-bean=”personServiceFactory” factory-method=”createOrder”>

 

Bean的作用域:

.singleton在每個Spring IoC容器中一個bean定義只有一個對象實例,默認情況下會在容器啓動時初始化bean.但我們可以指定Bean節點的lazy-init=”true”來延遲初始化bean,這時候,只有第一次獲取bean會才初始化bean。如:

<bean id=”xxx” class=”cn.itcast.OrderServiceBean” lazy-init=”true” />

如果想對所有的bean都應用延遲初始化,可以在跟節點beans設置default-laza-init=”true”,如下: <beans default-lazy-init=”true”>

.prototype 每次從從其獲取bean都是新的對象。

以下僅用於Web Bean

.request

.session.

.global session

 

Spring管理Bean的聲明週期:

init-method: bean初始化實例時,調用初始化方法。

destroy-method bean被銷燬時執行的方法

AbstractApplicationContext.close()方法用於關閉Spring容器

Spring的依賴注入:

使用內部bean,但該bean不能被其他bean使用:

<bean id=”orderService” class=”cn.itcast.service.OrderServiceBean”>

<property name=”orderDao”>

      <bean class=”cn.itcast.service.OrderDaoBean” />

</property>

</bean>

 

JavaBean是一種特殊的Java類,主要用於傳遞 數據信息,這種java類中的方法主要用於訪問私有的字段,且方法名符合某種命名規則。

如果要在兩個模塊之間傳遞多個信息,可以將這些信息封裝到一個JavaBean中,這種JavaBean的實例對象稱之爲值對象(Value Object,簡稱VO)。這些信息在類中用私有字段來存儲,如果讀取或設置這些字段的值,則需要通過一些相應的方法來訪問。JavaBean的屬性是根據啓動的settergetter方法來確定的,而不是根據其中的成員變量。如果方法名爲setId,中文意思即爲設置id,至於你把它設置到那個變量上,則不用關心,如果方法名爲getId,則屬性名即爲id.

JDK中提供了對JavaBean進行操作的一些API。這套API就稱爲內省

spring集合類型的封裝:

<property name="sets">

           <set>

              <value>value1</value>

              <value>value2</value>

              <value>vaule3</value>

              <value>value4</value>

           </set>

       </property>

       <property name="lists">

           <list>

              <value>list1</value>

              <value>list2</value>

              <value>list3</value>

           </list>

       </property>

       <property name="maps">

           <map>

              <entry key="key1" value="value1" />

              <entry key="key2" value="value2" />

           </map>

       </property>

       <property name="props">

           <props>

              <prop key="p1">v1</prop>

           </props>

       </property>

 

spring依賴注入的實現:

private static class MyApplicationContect {

       public static Object getBean(String name) throws Exception {

          

           Map<String, String> nsMap = new HashMap<String, String>();

          

           // 加入命名空間

           nsMap.put("ns", "http://www.springframework.org/schema/beans");

          

           // 創建beans/bean的路徑

           XPath xsub = document.createXPath("/ns:beans/ns:bean[@id='" + name + "']");

          

           // 設置命名空間

           xsub.setNamespaceURIs(nsMap);

          

           Element ele = (Element)xsub.selectSingleNode(document);;

           System.out.println(ele.attributeValue("class"));

          

           Object retValue = Class.forName(ele.attributeValue("class")).newInstance();

          

           for (Iterator<?> iter=ele.elementIterator("property"); iter.hasNext();) {

             

              Element property = (Element)iter.next();

              String propName = property.attributeValue("name");

             

              if (property.attributeValue("value") != null) {

                  String strValue = property.attributeValue("value");

                  Class<?> paraType = retValue.getClass().getDeclaredField(propName).getType();

                  Object value = ConvertUtils.convert(strValue, paraType);

                 

                  setProperty(retValue, propName, value);

                  //BeanUtils.setProperty(retValue, propName, strValue);

              } else {

                  String ref = property.attributeValue("ref");

                  Object obj2 = getBean(ref);

                 

                  setProperty(retValue, propName, obj2);

                  //BeanUtils.setProperty(retValue, propName, obj2);

              }

           }

           return retValue;

       }

      

       private static void setProperty(Object object, String propertyName,

              Object propertyValue) throws IntrospectionException,

              IllegalAccessException, InvocationTargetException {

           PropertyDescriptor propertyX = new PropertyDescriptor(propertyName, object.getClass());

           Method methodSetX = propertyX.getWriteMethod();

           methodSetX.setAccessible(true);

           methodSetX.invoke(object, propertyValue);

       }

    }

 

依賴注入共有三種:

使用構造器注入

使用屬性setter方法注入

使用Field注入(用於註解注入)

注入依賴對象可以採用手工裝配或自動裝配,在實際應用中建議使用手工裝配,因爲自動裝配會產生未知情況,開發人員無法預見最終的裝配結果。

手工裝配依賴對象,在這種方式中又有兩種編程方式。

1.     xml配置中,通過在bean節點下配置(通過構造器注入,通過setter方法注入)

2.     java代碼中使用@Autowired@Resource註解方式進行裝配。但我們需要在xml配置文件中配置下面的

<context:annotation-config />這個配置方式註冊了多個註釋進行解析處理的處理器

AutowireAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor,PersistenceAnnotationBeanPostProcessorRequiredAnnotationBeanPostProcessor

注:@Resource註解在spring安裝目錄的lib/j2ee/common-annotations.jar

java代碼中使用@Autowired@Resource註解方式進行裝配,這兩個註解的區別是:@Autowired默認按類型裝配@Resource默認按名稱裝配,當找不到與名稱匹配的bean時,纔會按類型裝配

@Autowired

private PersonDao personDao; // 用於字段上

@Autowired

public void setOrderDao(OrderDao orderDao) { // 用於屬性的setter方法上

}

@Autowired註解是按類型裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null,可以設置它的required屬性爲false,如果我們想使用按名稱裝配,可以結合@Qualified註解一起使用。如下:

Autowired @Qualifer(“personDaoBean”);

  private PersonDao personDao;

@Resrouce註解和@Autowired一樣,也可以標註在字段或屬性的setter方法,但它默認按名稱裝配,名稱可以通過@Resourcename屬性指定,如果沒有指定name屬性,當註解標註在字段上,即默認取字段的名稱作爲bean名稱尋找依賴對象,當註解標註在屬性的setter方法上,即默認取屬性名作爲bean名稱尋找依賴對象。

@Resource(name=”personDaoBean”)

private PersonDao personDao // 用於字段上

注意:如果沒有指定name屬性,並且按照默認的名稱仍然找不到依賴對象時,@Resource註解會回退到按類型裝配,但一旦指定了name屬性,就只能按名稱裝配了。

 

自動裝配的實現:<bean id=”” class=”” autowire=”byType”>

autowire屬性取值如下:

.byType: 按類型裝配,可以根據屬性的類型,在容器中尋找跟類型匹配的bean,如果發現多個,那麼就會拋出異常,如果沒有找到,即屬性值爲null

.byName 按名稱裝配,可以根據屬性的名稱,在容器中尋找跟屬性名相同的bean.如果沒有找到,即屬性值爲null.

.constructorbyType的方式類似,不同之處在於它應用於構造器參數,如果在容器中沒有找到與構造器參數類型一致的bean,那麼將會拋出異常。

autodeleted,通過bean類的自省機制(introspection來決定是使用constructor還是byType方式進行自動裝配。如果發現默認的構造器,那麼將使用byType方式。

spring2.5爲我們引入了組件自動掃描機制,他可以在類路徑下尋找標註了@Component,@Service,@Controller,@Repository註解的類,並把這些類納入進spring容器中管理,它的作用和在xml文件中使用bean節點配置組件是一樣的,要使用自動掃描機制,我們需要在配置文件中配置以下信息:

<context:component-scan base-package=”cn.itcast”>

其中base-package爲需要掃描的包(含子包)

@Service用於標註業務層組件@Controller用於標註控制層組(struts中的action)@Repository用於標註數據訪問組件,即DAO組件,而@Component泛指組件,當組件不好歸類時,我們可以使用這個註解進行註冊。

 

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