Spring入門-容器&創建對象&作用域&生命周期


Spring是Java里非常經典的框架,由Rod Johnson創建,其已經成為Java EE行業標准,用於解決一站式服務,接下來入門學習一下。

什么是Spring

開源的,用來簡化企業級應用開發的應用開發框架,是一款輕量級的框架,一共有2200多個類。

簡化開發

Spring對常用的API做了封裝(比如JDBC),這樣就可以大大簡化這些API的使用,如SpringJDBC的使用,不需要我們考慮創建連接和關閉連接。

解耦

設計有一個基本原則,即高內聚低耦合,即類的職責越單一越好,並且對類進行維護時,避免"牽一發動全身"的情況。

高內聚:類的職責需要單一

低耦合:Spring幫忙建立對象之間的依賴關系,對象之間的耦合度會大大降低,代碼的可維護性大大提高以前如果A類需要調用B類的一個方法,需要先在A類中先new一個B類的對象,然后調用B類對象的方法如果A類不想調用B類的方法,想改成調用C類的方法,則A類中的語句需要相應的修改,耦合度就相應提高了Spring的出現,自動幫忙管理對象之間的依賴關系,對象通過容器和配置文件來創建,降低耦合度

集成其他框架

Spring可以將其他的一些框架集成進來(比如定時任務處理的Quartz,數據庫連接相關的MyBatis),方便這些框架的使用。在Spring管理對象的基礎上,將對象進行調用會比自己手動使用配置文件創建后調用更加的方便。

Spring容器

Spring容器是Spring框架中的一個核心模塊,用於管理對象,所謂容器就是用來創建管理對象並建立對象之間依賴關系的,以前學習的Tomcat就是一種容器,其有初始化和銷毀對象方法。

啟動Spring容器

啟動Spring容器分為如下幾步,前提是Maven的項目:

(1)導包:使用pom.xml導入spring-mvc的包

1 <!-- 導入spring-webmvc的jar包 -->
2   <dependency>
3   <groupId>org.springframework</groupId>
4   <artifactId>spring-webmvc</artifactId>
5   <version>4.2.3.RELEASE</version>
6   </dependency>

(2)添加Spring啟動時讀取的配置文件,一般名為applicationContext.xml,本次使用myApplicationContext.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"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
    xmlns:jee="http://www.springframework.org /schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
        http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">    
        
</beans>
View Code

(3)啟動容器 

本次使用一個測試類來完成啟動。

 1 package test;
 2 
 3 import org.junit.Test;
 4 import org.springframework.context.ApplicationContext;
 5 import org.springframework.context.support.ClassPathXmlApplicationContext;
 6 
 7 public class TestSpring {
 8     @Test
 9     public void testStartSpring() {
10         //測試啟動Spring容器
11         String[] path= new String[]{"myApplicationContext.xml"};
12         ApplicationContext ac=new ClassPathXmlApplicationContext(path);    
13         System.out.println(ac);
14     }    
15 }
View Code

啟動結果,正常啟動並打印出對象,並顯示啟動時間。

使用Spring容器創建對象

Spring容器創建對象有三種方式,用的多的就是第一種方式,創建對象需要在myApplicationContext.xml配置bean屬性,讓Spring幫忙創建,配置在xml中的屬性相當於配方,Spring根據配方來創建對應的對象。

(1)使用無參數構造器創建

(2)使用靜態工廠方法創建

(3)使用實例化對象工廠方法創建

配置文件內容

bean id:需獨一無二,bean的名字。

class屬性:創建對象對應的類

factory-method:類的靜態工廠方法,如Calendar類中有getInstance靜態方法

factory-bean:指定一個bean的id,容器會調用該bean的實例方法來創建一個對象

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3     xmlns:context="http://www.springframework.org/schema/context" xmlns:util="http://www.springframework.org/schema/util"  
 4     xmlns:jee="http://www.springframework.org /schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
 5     xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
 6     xsi:schemaLocation="
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
 9         http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
10         http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
11         http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
12         http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
13         http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">    
14         
15         <!-- 使用無參數構造器 -->
16         <bean id="person" class="com.boe.Person"></bean>
17         
18         <!-- 使用靜態工廠方法 -->
19         <bean id="cal" class="java.util.Calendar" factory-method="getInstance"></bean>
20         
21         <!-- 使用實例化對象工廠方法 -->
22         <bean id="date" factory-bean="cal" factory-method="getTime"></bean>
23         
24 </beans>

測試類中內容

 1 package test;
 2 
 3 import java.util.Calendar;
 4 import java.util.Date;
 5 
 6 import org.junit.Test;
 7 import org.springframework.context.ApplicationContext;
 8 import org.springframework.context.support.ClassPathXmlApplicationContext;
 9 
10 import com.boe.Person;
11 
12 public class TestSpring {
13     @Test
14     public void testStartSpring() {
15         //測試啟動Spring容器
16         String[] path= new String[]{"myApplicationContext.xml"};
17         ApplicationContext ac=new ClassPathXmlApplicationContext(path);    
18         System.out.println(ac);
19     }    
20     
21     @Test
22     public void testGetInstance() {
23         String[] path= new String[]{"myApplicationContext.xml"};
24         ApplicationContext ac=new ClassPathXmlApplicationContext(path);    
25         //方法1
26         Person person=ac.getBean("person",Person.class);
27         System.out.println(person);
28         //方法2
29         Calendar calendar=ac.getBean("cal",Calendar.class);
30         System.out.println(calendar);
31         //方法3
32         Date date=ac.getBean("date",Date.class);
33         System.out.println(date);
34     }
35 }
View Code

測試結果

作用域和延遲加載

作用域:默認情況下,容器對每個bean元素只會創建一個實例對象,如果將作用域設置為prototype,則每次調用getBean方法,就會創建一個新的對象。另外作用域默認為singleton

在上面配置文件基礎上加一條配置。bean id為'p'的對象用於測試,分別測試scope屬性為singleton和prototype。注意其他關於Person類的配置先注釋,方便測試。

<!-- 測試作用域 -->
<bean id="p" class="com.boe.Person" scope="singleton"></bean>

測試代碼

//測試作用域
    @Test
    public void testScope() {
        String[] path= new String[]{"myApplicationContext.xml"};
        ApplicationContext ac=new ClassPathXmlApplicationContext(path);    
        Person p1=ac.getBean("p",Person.class);
        Person p2=ac.getBean("p",Person.class);
        System.out.println(p1.equals(p2));
    }

當scope為singleton時

當scope為prototype時

可以看出作用域為singleton時,對象只創建了一次,並且兩者相等,雖然使用getBean方法兩次,但是卻只有一個對象,似乎對象不是getBean方法獲得,這跟后面要說的延遲加載有關。

當作用域為prototype時,創建了兩個對象,並且兩者不相等,說明使用一個getBean方法,就創建了一個新的對象。

延遲加載:默認情況下容器啟動之后,會將作用域為singleton的bean創建好,設置延遲加載容器啟動之后,對作用域為singleton的bean不再創建,到調用getBean方法才會創建,設置延遲加載需在配置文件中設置lazy-init屬性。

<!-- 測試作用域 -->
<bean id="p" class="com.boe.Person" scope="singleton" lazy-init="true"></bean>

測試分為以下幾種情況,根據控制台輸出情況得到如下結果:

(1)scope="singleton",lazy-init="false":啟動容器就創建對象,並且只有一個

(2)scope="singleton",lazy-init="true":啟動容器不會創建對象,直到調用getBean方法才會創建對象,並且只有一個

(3)scope="prototype",無論是否設置延遲加載,均只有在調用getBean方法才會創建對象,並且是創建多個不同的對象

對象生命周期

對象生命周期管理可以用來更好的分配資源,其有初始化方法和銷毀方法,可以在xml配置文件中對方法進行指定,只對作用域為singleton的有效。

初始化方法:Spring容器創建好bean的實例后,會調用初始化方法

銷毀方法:容器關閉后會調用銷毀方法,將spring容器管理的對象全部銷毀

配置文件內容

1 <!-- 測試生命周期,對初始化方法和銷毀方法進行配置-->
2 <bean id="message" class="com.boe.MessageService" init-method="init" destroy-method="destroy"></bean>
3     

MessageService類

 1 package com.boe;
 2 
 3 public class MessageService {
 4 
 5     public MessageService() {
 6         System.out.println("構造方法MessageService()執行了,完成創建對象");
 7     }
 8     
 9     /**
10      *  做成初始化方法,希望spring容器創建好MessageService對象后,馬上調用init()方法
11      *  方法:需要修改容器配置文件,讓容器知道這個是MessageService的初始化方法
12      */
13     public void init() {
14         System.out.println("初始化方法init()執行了");
15     }
16     
17     /**
18      * 做成銷毀方法,配置文件也需要說明
19      */
20     public void destroy() {
21         System.out.println("銷毀方法destroy()執行了");
22     }
23 }
View Code

測試代碼

1     //測試生命周期
2     @Test
3     public void testLife() {
4         String[] path= new String[]{"myApplicationContext.xml"};
5         AbstractApplicationContext ac=new ClassPathXmlApplicationContext(path);    
6         ac.close();
7     }

測試結果,可以看出不設置延遲加載,singleton作用域的對象在容器啟動后就創建,並隨后執行了對象初始化方法,當容器關閉,就會執行銷毀方法。

 

結論

(1)Spring是一個提供一站式服務的框架,可以使用Spring容器和配置文件來創建和管理對象

(2)創建對象方式有3種方式

(3)作用域有singleton和prototype,默認為前者,設置延遲加載只對singleton有效。

(4)對象生命周期管理可以更好的分配資源

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM