Spring的基本用法(大全)

Spring的簡介

基於依賴注入的核心機制、基於AOP的聲明式事務管理,與多種持久層技術的整合。使用Spring框架必須使用Spring Core Container只要由org.springframework.core、org.springframework.beans、org.springframework.context、org.springframework.expression四個包及其子包組成。

  1. 像大工廠一樣,負責創建、管理所有Java對象,這些Java對象就是Bean。
  2. 管理容器中Bean之間的依賴關係
  3. 本質是通過XML配置文件來驅動Java代碼

使用Spring管理bean

Spring容器是一個工廠。

Bean是Spring容器管理的對象,一切Java對象都可以是Bean

bean與Java Bean的不同

  • 寫法不同:Java Bean必須遵守特定的規範,必須給每個屬性提供對應的getter和setter方法,而Bean只需提供setter方法。
  • 用處不同:Bean是Java實例、Java組件,JavaBean通常作爲DTO(數據傳輸對象)來封裝值對象,來傳遞參數
  • 生命週期不同:JavaBean作爲值對象傳遞,不接受任何容器管理其生命週期。Bean由Spring管理生命週期。
<?xml version="1.0" encoding="UTF-8"?>
<beans>
 <!-- 配置db.properyies文件位置 -->
    <bean id="configurer" class="org.springframework.beans.factory.config.PreferencesPlaceholderConfigurer">
        <property name="locations" value="classpath:db.properties"></property>
    </bean>
</beans>

<bean/>驅動spring以反射方式調用該類無參的構造器。id爲Bean的唯一標識,通過id屬性值訪問Bean和管理Bean之間的依賴。class指定Bean的實現類。

<property/>驅動spring在底層以反射執行setter方法賦值。 name屬性決定執行哪個setter方法,value或ref決定執行setter方法傳入的參數。ref可指定一個bean屬性,該屬性用於引用容器內中其他Bean實例的id屬性值。

<value><property/>的子元素相當於value,可指定調用setDriverClass()方法。的參數值爲com.mysql.jdbc.Driver。設值注入。現在用得少。

 

程序通過Spring容器來訪問容器中的Bean,ApplicationContext是Spring容器最常用的接口,有如下兩種實現類:

  • ClassPathXmlApplicationContext:從類加載路徑下搜索配置文件,根據配置文件創建Spring容器。通常用這個。
  • FileSystemXmlApplicationContext:從文件系統的相對路徑
public class BeanTest
{
    public static void main(String[] args)throws Exception{
//  創建Spring容器
        ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");
        // 獲取id爲person的Bean
        Person p = ctx.getBean("person",Person.Class);
 
    }
}

Spring的核心機制:依賴注入(DI ,Dependency Injection)

依賴:A對象調用B對象的方法,即A對象依賴於B對象。

注入普通的屬性值,還可以注入其他Bean的引用。當某個Java實例需要其他Java實例時,系統自動提供所需實例,無需程序顯示獲取。

工廠模式和被依賴對象的接口耦合,被依賴對象交給工廠創建。

現在只需被動的等待Spring容器注入。

實現方法:

  • 設值注入。IOC(控制反轉)容器使用成員變量的setter方法來注入被依賴對象
  • 構造注入。IOC(控制反轉)容器使用構造器來注入被依賴對象

Spring推薦面向接口編程。不論調用者還是被依賴者都定義爲接口。也可以通過註解,利用反射創建實例。

public class Chinese implements Person{
    private Axe axe;
//設值注入所需的setter方法
    public void setAxe(Axe axe){
        this.axe=axe;
    }
    public void useAxe(){
// 實現Person接口的useAxe方法
        System.out.println(axe.chop());
//調用chop方法,表明Person對象依賴於axe對象
    }
}

使用XML配置文件指定實例之間的依賴關係。

構造注入

通俗來說,就是驅動Spring底層以反射方式執行帶指定參數的構造器。

問題:<bean/>總是驅動Spring執行無參的構造器來創建對象,怎麼驅動Spring執行有參數的構造器???

答案是<contructor-arg  />子元素。<contructor-arg  />子元素代表一個構造器參數。

public class Chinese implements Person{
    private Axe axe;
//構造注入所需的帶參數的構造器
    public Chinese(Axe axe){
        this.axe=axe;
    }
    public void useAxe(){
// 實現Person接口的useAxe方法
        System.out.println(axe.chop());
//調用chop方法,表明Person對象依賴於axe對象
    }
}

//對應的配置文件添加<contructor-arg  />子元素

優先依賴的,優先注入。

建議:以設值注入爲主,構造注入爲輔。依賴關係無需變化的注入,就是用構造注入。

Spring的核心接口

ApplicationContextBeanFactory,ApplicationContext是BeanFactory的子接口

BeanFactory

方法

  • boolean containsBean(String name):
  • <T> T getBean(Class<T> requiredType)返回屬於requiredType類型的Bean實例。Object getBean(String name)容器id爲name的Bean實例
  • Class<?> getType(String name)

注意事項

  1. 創建BeanFactory實例時,必須提供XML配置文件作爲參數,XML配置文件通常使用Resource對象傳入。(Resource接口是Spring提供的資源訪問接口)
  2. 如果需要加載多個配置文件來創建Spring容器,利用ApplicationContext來創建SessionFactory的實例。
ApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml","service.xml");

ApplicationContext

使用ApplicationContext實例作爲容器,Spring的上下文。

允許以聲明式方式操作容器,除了提供BeanFactory所支持的全部功能外,還支持如下功能:

  • ApplicationContext默認會預初始化所有的singleton Bean,也可通過配置取消預初始化。不加特殊配置,Bean默認爲singleton行爲
  • ApplicationContext繼承MessageSource接口,提供國際化支持。
  • 資源訪問,如URL和文件
  • 事件機制
  • 同時加載多個配置文件
  • 以聲明式方式啓動創建Spring容器

優先使用ApplicationContext

<bean />元素指定lazy-init="true"阻止容器預初始化該Bean

ApplicationContext的國際化支持

ApplicationContext繼承MessageSource接口,提供國際化支持

String  getMessage(String code,Object[] args,Locale loc)

String getMessage(String code,Object[] args,Locale loc)

ApplicationContext的事件機制

ApplicationContext的事件機 制是觀察者設計模式實現。通過ApplicationEvent(容器事件)和ApplicationListener(監聽器)接口實現事件處理。

事件源、事件和事件監聽器組成

Spring容器中的Bean

  • 開發Bean
  • 配置Bean

Bean的基本定義和別名

<beans />元素是Spring的根元素,屬性如下:

  • default-merge:指定所有Bean默認的merge行爲
  • default-lazy-init:指定所有Bean默認的延遲初始化
  • default-autowire:自動裝配行爲。no、byName、byType、constructor、autodetect
  • default-autowire-candidates:指定所有Bean默認是否作爲作爲自動裝配的候選Bean。不做自動裝配設爲false。
  • default-init-method:初始化方法
  • default-destroy-method:回收方法

定義Bean時,通常指定兩個屬性:

  • id:Bean的唯一標識
  • class:實現類
  • name:指定別名,多個別名可用逗號、冒號、空格
  • <alias />子元素爲已有的Bean指定別名。name:指定Bean實例的標誌,alias:別名

容器中Bean的作用域

5種作用域:

  • singleton(常用):默認單例,整個Spring IOC容器中,singleton只生成一個bean實例
  • prototype(常用):每次通過容器的getBean()方法獲取prototype作用域的Bean,都將產生新的實例
  • request:對於一次HTTP請求,request作用域的Bean就只生成一個實例。Web應用中生效
  • session:對於一次HTTP會話,session作用域的Bean就只生成一個實例。Web應用中生效
  • global session:每個全局的HTTP session對應一個作用域。僅在使用portlet context有效,Web應用中生效。

使用自動裝配注入合作者Bean

通過<bean />的autowire屬性指定或<beans />的default-autowire指定。屬性值如下:

  • no
  • byName:根據setter的方法名。沒找到匹配BeanSpring不做任何事情。 
  • byType:根據setter的方法參數類型。容器包含多於一個的匹配參數類型實例就會拋出異常。
  • constructor:與byType相似,區別在於自動匹配構造器的參數。如果找不到匹配與構造器參數類型匹配的Bean就會拋出錯誤
  • autodetect:Spring根據Bean內部結構,自行決定使用construct或byType策略。如果是默認構造函數就會使用byType。

注入嵌套Bean

如果某個Bean所依賴的Bean不想被Spring容器直接訪問,可以使用嵌套Bean。

嵌套Bean:把<bean />作爲<property/>或<contructor-args/>的子元素,那麼該<bean/>元素配置的Bean僅僅作爲setter注入、構造注入的參數。由於容器不能獲取嵌套Bean,所以不用指定id

本質上與使用ref引用容器中的另一個Bean一樣。

小貼士

  • 形參類型是基本類型、String、日期等,用value指定字面值即可。
  • 形參類型是複合類(如Person、Dog、DataSource等Java對象)作爲實參。1.使用ref引用容器中已配置的Bean(Java對象)2.使用<bean/>元素配置嵌套Bean

注入集合值

在<property/>元素下添加<list/>、<set/>、<map/>和<props/>設置集合參數值

<property name="">
<list>
<!--每個value、ref、bean都配置List元素 -->
    <value>小學</value>
    <value>中學</value>
</list>
<property/>
<property name="">
<map>
    <entry key="" value=""/>
    <entry key="" value=""/>
</map>
<property/>
<property name="">
<map>
    <entry key="" value-ref=""/>
    <entry key="" value-ref=""/>
</map>
<property/>

<property name="">
    <props>
<!--每個key、value只能是字符串 -->
        <prop key="屬性名"></prop>
        <prop key="血壓">125</prop>
        <prop key="身高">163</prop>
    <props/>
<property/>

<property name="">
<set>
<!--每個value、ref、bean都配置set元素 -->
    <value>普通字符串</value>
    <bean class="類的路徑" />
    <ref bean="類名" />
    <list>
        <value></value>
        <set>
            <value type="int"></value>
        </set>
    </list>
</set>
<property/>

組合屬性

除最後一個屬性外,其他屬性不能爲null

 

Java配置管理

Java配置類的三個Annotation

  • @Configuration:用於修飾配置類
  • @Bean:修飾一個方法,將該方法的返回值定義成容器中的一個Bean
  • @Value:修飾Field,爲該Field配置一個值
  • @Import:修飾Java配置類,用於向當前Java配置類中導入其他Java配置類
  • @Scope:修飾一個方法,方法對應的Bean的作用域
  • @Lazy:修飾一個方法,方法對應的Bean是否延遲初始化
  • @DependsOn:修飾一個方法,指定在初始化該方法對應的Bean及其依賴關係之前初始化指定的Bean。

以XML配置方式爲主,需要在XML配置中加載Java類配置

<!-- 加載Java配置類 -->
<bean class="org.crazyit.app.config.AppConfig">

以Java類配置爲主,藉助@ImportResources註解修飾Java配置類

@Configuration
// 導入XML配置
@ImportResources("classpath:/beans.xml")

創建Bean的3種方式

  • 調用構造器創建Bean
  • 調用靜態工廠方法創建Bean
  • 調用實例工廠方法創建Bean

調用構造器創建Bean

如果不採用構造注入,Spring底層默認調用Bean類的無參構造器創建實例。所有基本類型初始化爲0或false,所有引用類型初始化爲null。根據配置文件實例化被依賴的Bean,爲Bean注入依賴關係,最後將一個完整的Bean實例返回程序。

調用靜態工廠方法創建Bean

<bean />必須指定class屬性。此時class指定的是靜態工廠類。還需要使用factory-method屬性指定靜態工廠方法。Spring調用靜態工廠方法返回Bean實例。

public class BeingFactory{
    //返回Being實例的靜態工廠方法
    //	參數arg決定返回哪個Being類的實例
	public static Being getBeing(String arg){
		if(arg.equalsIgnoreCase("dog")){
			return new Dog();
//			返回Dog實例
		}
//		否則返回Cat實例
		else{
			return new Cat();
		}
	}
}
<bean class="BeanFactory" factory-method="getBeing">
<!-- 配置靜態工廠方法的參數 -->
<constructor-arg value="dog"/>
<property name="msg" value="the dog"/>
</bean>

調用實例工廠方法創建Bean

實例工廠和靜態工廠只有一點不同:調用靜態工廠方法只需使用工廠類,而調用實例工廠需要工廠實例。

配置靜態工廠方法使用class指定靜態工廠類,配置實例工廠使用factory-bean指定工廠實例。

使用實例工廠時,<bean/>無須class屬性,Spring容器調用實例工廠的工廠方法創建Bean實例。

實例工廠方法創建<bean/>元素時需要指定的屬性:

  • factory-bean:指定工廠Bean的id
  • factory-method:指定實例工廠的工廠方法

抽象Bean與子Bean

<bean/>元素下添加abstract="true",不指定class就是抽象Bean,不能被實例化,只能被繼承

<bean/>元素下添加parent="父Bean的id",該bean是一個子bean.

Bean繼承和Java繼承的區別

  • Spring中子Bean與父Bean可以是不同類型,Java繼承保證子類是特殊父類
  • Bean的繼承是實例間的關係,主要表現在參數值的延續。Java繼承是類之間的關係,主要表現在方法、屬性的延續。
  • 子Bean不能作爲父Bean使用,不具備多態性,Java繼承子類實例可以當父類實例使用

工廠Bean:與前面不同,Spring的一種特殊Bean,必須實現FactoryBean接口。返回該Bean實例的getObject()方法的返回值。開發者實現getObject()方法。(返回某個類型的值)

容器中Bean的生命週期

Spring可以管理singleton作用域的Bean的生命週期,Spring可以精確的知道該Bean何時被創建、初始化完成、何時準備銷燬該實例。

prototype作用域的Bean,Spring僅僅負責創建。其他就交給客戶端代碼管理,無法管理。

注入依賴關係之後

  • 使用init-method屬性:指定某個方法在Bean注入依賴關係之後自動執行
  • InitializingBean接口:在爲Bean注入依賴關係之後實現void afterPropertiesSet() throws Exception

Bean銷燬之前

  • 使用destroy-method屬性:指定某個方法在Bean銷燬之前自動執行
  • 實現disposableBean接口:void destroy() throws Exception

獲取其他Bean的屬性值

PropertyPathFactoryBean用來獲取其他Bean的屬性值。(實際上就是getter方法的返回值)

  • 調用哪個對象:由PropertyPathFactoryBean的setTargetObject(Object targetObject)方法指定
  • 調用哪個getter方法:由PropertyPathFactoryBean的setPropertyPath(String propertyPath)方法指定。
<bean class="" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetBeanName" value="person"/>
<property name="propertyPath" value="son"/>
</bean>

<util:property-path/>作爲PropertyPathFactoryBean簡化配置。id屬性:指定getter方法的返回值定義成名爲id的Bean實例。path:指定哪個Bean實例、哪個屬性暴露出來。

獲取Field值

通過FieldRetrievingFactoryBean類,可訪問類的靜態Field或對象的實例Field值。可將獲取的值注入到其他Bean,也可直接定義新的Bean。<util:constant/>

<bean class="" class="org.springframework.beans.factory.config.PropertyPathFactoryBean">
<property name="targetClass" value="java.sql.Connection"/>
<property name="targetField" value="TRANSACTION_SERIALIZABLE"/>
</bean>

獲取方法返回值

通過MethodInvokingFactoryBean工廠Bean,可以獲取任意類的類方法。

SpEL

Spring表達式語言即SpEL。略

Spring的零配置支持

  • @Component:標註普通Java Bean類,首字母小寫,其他不變
  • @Controller:控制器組件類
  • @Service:業務邏輯組件類
  • @Repository:DAO組件類
  • @Scope:作用域
  • @Resource(name=" ")和<property/>的ref效果相同,可以省略name。修飾setter方法或實例變量
  • @PostConstruct修飾的方法是Bean創建之後執行方法
  • @PreDestroy修飾的方法是Bean銷燬之前執行方法
  • @DependsOn:強制初始化其他Bean
  • @Lazy:指定Bean是否取消預初始化。延遲。
  • @Autowired:自動裝配,可以修飾setter方法、普通方法、實例變量和構造器。默認採用byType自動裝配策略
  • @Qualifier:根據Bean的id執行自動裝配

 

自動掃描指定包及其子包下的所有Bean類<context:component-scan base-package="org.crazyit.app.service"/>

<context:component-scan base-package="org.crazyit.app.service">
    <context:include-filter type="regex" expression=".*Chinese"/>
    <context:include-filter type="regex" expression=".*Axe"/>
</context:component-scan>

<context:exclude-filter>或<context:include-filter>子元素指定Spring Bean類,只要位於指定路徑下的Java類滿足這個規則,就會當成Bean類處理。

type:指定過濾器類型

expression:過濾器所需要的表達式

Spring內建支持的4種過濾器:annotation(annotation過濾器)、assignable(類名過濾器)、regex(正則表達式)、aspectj(aspectj過濾器)

 

資源訪問

資源=>XML配置文件、二進制流等各種類型文件

Resource接口的實現類有UrlResource等

  1. 訪問網絡資源
  2. 訪問類加載路徑下的資源
  3. 訪問文件系統資源
  4. 訪問應用相關資源
  5. 訪問字節數組資源

ApplicationContext中使用資源

1.使用ApplicationContext實現類指定訪問策略

  • ClassPathXmlApplicationContext:對應使用ClassPathResource進行資源訪問
  • FileSystemXmlApplicationContext:對應使用FileSystemResource進行資源訪問
  • XmlWebApplicationContext:對應使用ServletContextResource進行資源訪問

2.使用前綴指定訪問策略

http:、ftp:等前綴,用來確定對應的資源訪問策略。

3.classpath*:前綴用法

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