JavaWeb Spring開發入門深入學習_java

來源:互聯網
上載者:User

1 Spring基本特徵

Spring是一個非常活躍的開源架構;它是一個基於Core來構架多層JavaEE系統的架構,它的主要目地是簡化企業開發.
Spring以一種非侵入式的方式來管理你的代碼,Spring提倡”最少侵入”,這也就意味著你可以適當的時候安裝或卸載Spring,Spring讓java亮了。 (開放–閉合原理),這裡是閉原則。

2 開發spring所需要的工具

(這裡先將spring2.5 ,後面3.0)

2.1 Spring的jar包

到http://www.springsource.org/download下載spring,然後進行解壓縮,在解壓目錄中找到下面jar檔案,拷貝到類路徑下

—spring的核心類庫 在spring文檔的dist下 dist\spring.jar

—引入的第三方類庫 都spring文檔的lib下,lib\jakarta-commons\commons-logging.jar

—如果使用了切面編程(AOP),還需要下列jar檔案 lib/aspectj/aspectjweaver.jar和aspectjrt.jarlib/cglib/cglib-nodep-2.1_3.jar

—如果使用了JSR-250中的註解,如@Resource/@PostConstruct/@PreDestroy,還需要下列jar檔案lib\j2ee\common-annotations.jar

注:JSR(Java 規範請求)是指向JCP(Java Community Process)提出新增一個標準化技術規範的正式請求。任何人都可以提交JSR(Java 規範請求),以向Java平台增添新的API和服務。JSR已成為Java界的一個重要標準

2.2 Spring設定檔

預設情況下是applicationContext.xml檔案。可以建立很多xml檔案,工程中一般都是這樣配置的。(src目錄下建)

3 Spring準系統詳解

3.1 SpringIOC

Spring的控制反轉:把對象的建立、初始化、銷毀等工作交給spring容器來做。由spring容器控制對象的生命週期。

步驟:
 •A. 啟動spring容器
1、 在類路徑下尋找設定檔來執行個體化容器

複製代碼 代碼如下:
 ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{"applicationContext.xml"});

可以在整個類路徑中尋找xml檔案
* 通過這種方式載入。需要將spring的設定檔放到當前項目的classpath路徑下
* classpath路徑指的是當前項目的src目錄,該目錄是java源檔案的存放位置。

2、 在檔案系統路徑下尋找設定檔來執行個體化容器

Spring的設定檔可以指定多個,可以通過String數組傳入。
註:經常用第一種方法啟動容器
 •B. 從spring容器中提取對象 

spring 容器結構:

3.2 別名

<beans> <alias name="person" alias="p"/>//alias這裡是別名,可以通過p,得到person這個bean. <bean name="person" class="cn.itcast.aliasspring.Person"/></beans>

通過這樣的配置,可以達到在一個地方命名,在多個地方使用不同的名字的效果。

3.3 Spring容器內部對象

1 建立對象的方式

1.1 無參建構函式

<bean id="helloWorld" class="com.itheima10.spring.createobject.HelloWorld"></bean>

 1.2 靜態Factory 方法

<bean id="helloWorld2" class="com.itheima10.spring.createobject.method.HelloWorldFactory"
factory-method="getInstance"></bean>

1.3 執行個體Factory 方法

<bean id="helloWorldFactory" class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean>
<bean id="helloWorld3" factory-bean="helloWorldFactory" factory-method="getInstance"></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-2.5.xsd"> <!--  把一個類放入到spring容器中,該類就稱為一個bean --> <!--  bean描述了一個類  id 唯一的標示  class 類的全名 --> <bean id="helloWorld" class="com.itheima10.spring.createobject.HelloWorld"></bean> <!-----------------------別名--------------------------------------> <!--  name的屬性和bean的id匹配 alias 別名 --> <alias name="helloWorld" alias="狗蛋"/> <alias name="helloWorld" alias="習近平"/><!-----------------------靜態Factory 方法--------------------------------------><!--  把helloWorldFactory放入到spring容器中 factory-method Factory 方法 --> <bean id="helloWorld2"  factory-method="getInstance"  class="com.itheima10.spring.createobject.method.HelloWorldFactory"></bean><!-----------------------執行個體Factory 方法--------------------------------------> <!--  把helloWorldFactory2放入到spring容器中 factory-bean 指明了工廠bean factory-method 指明了該工廠bean中的方法 --> <bean id="helloWorldFactory" class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean> <bean id="helloWorld3"  factory-bean="helloWorldFactory"  factory-method="getInstance"></bean></beans>

建立實體類HelloWorld

package com.itheima10.spring.createobject;public class HelloWorld { public void hello(){ System.out.println("hello"); }}

建立靜態工廠HelloWorldFactory

package com.itheima10.spring.createobject.method;public class HelloWorldFactory { public static HelloWorld getInstance(){ System.out.println("static method"); return new HelloWorld(); }}

建立實體工廠HelloWorldFactory2

package com.itheima10.spring.createobject.method;public class HelloWorldFactory2 { /** * 必須先建立工廠對象,才能調用該方法 * @return */ public HelloWorld getInstance(){ return new HelloWorld(); }}

編寫測試方法CreateObjectMethodTest

package com.itheima10.spring.createobject.method;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;/** * 第二種和第三種產生方式能看明白就OK了 * @author zd * */public class CreateObjectMethodTest { /** * 在預設情況下,spring容器調用的是一個類的預設的建構函式建立對象 */ @Test public void testCreateObject_Default(){ ApplicationContext context =   new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld"); helloWorld.hello(); } /** * 利用靜態工廠建立對象 * <bean id="helloWorld2"  factory-method="getInstance"  class="com.itheima10.spring.createobject.method.HelloWorldFactory"></bean>  spring容器做的事情:  利用HelloWorldFactory類調用了getInstance方法 */ @Test public void testCreateObject_StaticFactory(){ ApplicationContext context =   new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld2"); helloWorld.hello(); } /** * 執行個體Factory 方法建立對象 * <bean id="helloWorldFactory"  * class="com.itheima10.spring.createobject.method.HelloWorldFactory2"></bean> * <bean id="helloWorld3"  factory-bean="helloWorldFactory"  factory-method="getInstance"></bean> spring容器內部做的事情:  1、建立一個helloWorldFactory對象  2、由該對象調用getInstance產生helloWorld對象 */ @Test public void testCreateObject_InstanceFactory(){ ApplicationContext context =   new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld3"); helloWorld.hello(); }}

2 對象的scope

對象的scope有兩個屬性:singleton 與prototype。singleton表示單例
2.1 singleton(預設值)

在每個Spring IoC容器中一個bean定義只有一個對象執行個體(共用)。

2.2 prototype
允許bean可以被多次執行個體化(使用一次就建立一個執行個體) . Spring不能對一個prototype bean的整個生命週期負責.這就意味著清楚prototype範圍的對象並釋放任何prototype bean所持有的昂貴資源都是用戶端的責任。

<bean id="helloWorld" class="com.itheima10.spring.scope.HelloWorld" scope="singleton"></bean>
<bean id="helloWorld" class="com.itheima10.spring.scope.HelloWorld" scope="prototype"></bean>

建立HelloWorld類

public class HelloWorld { public List<String> lists = new ArrayList<String>(); public HelloWorld(){ System.out.println("new instance"); } public void hello(){ System.out.println("hello"); }}

建立測試類別ScopeTest

package com.itheima10.spring.scope;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class ScopeTest { /** * 把一個bean放入到spring容器中,預設的是單例 * 如果一個類放入到spring容易中,而這個類是單例的,那麼該類中的屬性將會成為共用的 */ @Test public void testCreateObject_Scope_Default(){ ApplicationContext context =   new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld hello1 = (HelloWorld)context.getBean("helloWorld"); hello1.lists.add("aaaa"); hello2= (HelloWorld)context.getBean("helloWorld"); hello2.lists.add("bbbb"); System.out.println(helloWorld.lists.size());//2,並且只輸出一次new instance } /** * 如果spring的設定檔如下: * <bean id="helloWorld"  class="com.itheima10.spring.scope.HelloWorld" scope="prototype"></bean> 那麼spring容器會為建立多個對象 */ @Test public void testCreateObject_Scope_Prototype(){ ApplicationContext context =   new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld hello1 = (HelloWorld)context.getBean("helloWorld"); hello1.lists.add("aaaa"); hello2= (HelloWorld)context.getBean("helloWorld"); hello2.lists.add("bbbb"); System.out.println(helloWorld.lists.size());//1,並且只輸出兩次new instance }}

3 初始化bean時機

懶載入——預設情況下會在容器啟動時初始化bean,但我們可以指定Bean節點的lazy-init=“true”來延遲初始化bean,這時候,只有第一次擷取bean會才初始化bean。如:

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

如果想對所有bean都應用延遲初始化,可以在根節點beans設定default-lazy-init=“true“,如下:

<beans default-lazy-init="true“ ...>

 Spring預設在啟動時將所有singleton bean提前進行執行個體化。提前執行個體化意味著作為初始化的一部分,ApplicationContext會自動建立並配置所有的singleton bean.通常情況下這是件好事。因為這樣在配置中有任何錯誤能立即發現。

Lazy-init 為false,spring容器將在啟動的時候報錯(比較好的一種方式)
Lazy-init 為true,spring容器將在調用該類的時候出錯。

配置applicationContext.xml

<bean id="helloWorld"  class="com.itheima10.spring.createobject.when.HelloWorld" scope="prototype"></bean></beans>

建立測試類別CreateObjectWhenTest

package com.itheima10.spring.createobject.when;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class CreateObjectWhenTest { /** * 預設情況下的順序 * 1、啟動spring容器 * 2、建立HelloWorld對象 * 3、對象調用方法 *  * <bean id="helloWorld" class="com.itheima10.spring.createobject.when.HelloWorld"></bean>  <bean id="helloWorld2" class="com.itheima10.spring.createobject.when.HelloWorld"></bean>  因為在spring容器中聲明了兩個bean,所以spring容器要建立兩個對象  說明:  如果struts2,hibernate,spring容器整合,如果spring的設定檔中出現錯誤  當 tomcat容器啟動的時候,就會報錯,錯誤會特別早的顯示出來  如果一個bean存放了大量的資料,這種方式不好,有可能會把資料過早的停留在記憶體中  如果一個bean不是單例,那麼不管怎麼樣配置,都在是context.getBean時才要建立對象 */ @Test public void testCreateObject_When_Default(){ ApplicationContext context =    new ClassPathXmlApplicationContext("applicationContext.xml"); context.getBean("helloWorld"); } /** * <bean id="helloWorld"  class="com.itheima10.spring.createobject.when.HelloWorld" lazy-init="true"></bean> * 順序 * 1、啟動spring容器 * 2、context.getBean * 3、調用構造器函數建立對象 * 說明:  如果struts2,hibernate,spring容器整合,如果spring的設定檔中出現錯誤  只有當用到該bean的時候才會報錯。  如果一個bean存放了大量的資料,需要的時候才要載入資料 */ @Test public void testCreateObject_When_Lazy(){ ApplicationContext context =    new ClassPathXmlApplicationContext("applicationContext.xml"); context.getBean("helloWorld"); }}

4 init、destroy方法

Spring初始化bean或銷毀bean時,有時需要作一些處理工作,因此spring可以在建立和拆卸bean的時候調用bean的兩個生命週期方法。可以指定方法進行操作。

 <bean id=“foo” class=“...Foo” init-method=“setup” destory-method=“teardown”/>

當foo被載入到Spring容器中時調用init-method方法。當foo從容器中刪除時調用destory-method(scope = singleton有效)

編寫HelloWorld

public class HelloWorld { public HelloWorld(){ System.out.println("new instance"); } public void init(){ System.out.println("init"); } public void destroy(){ System.out.println("destroy"); } public void hello(){ System.out.println("hello"); }}

編寫測試類別InitDestroyTest

package com.itheima10.spring.ioc.initdestroy;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class InitDestroyTest { /** * init-method="init" * 執行順序: * 1、啟動spring容器 * 2、建立helloWorld對象 * 3、執行init方法 *  spring容器內部自動執行的 * 4、對象調用方法 * 5、只有當spring容器關閉掉的情況下才能執行destroy方法 前提條件:bean是單例的 *  該方法也是由spring容器內部調用的 * 說明: * 如果一個bean不是單例的,則spring容器不負責對象的銷毀。 * 在spring容器中,只有一個bean是單例的情況下,spring容器才要負責對象的建立、初始化、銷毀工作 * 如果一個bean不是單例,spring容器只負責建立、初始化 */ @Test public void testInitDestroy(){ ApplicationContext context =  new ClassPathXmlApplicationContext("applicationContext.xml"); HelloWorld helloWorld = (HelloWorld)context.getBean("helloWorld"); helloWorld.hello(); ClassPathXmlApplicationContext applicationContext = (ClassPathXmlApplicationContext)context; applicationContext.close(); }}

執行順序圖:

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援雲棲社區。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.