1. 程式人生 > 實用技巧 >spring學習筆記

spring學習筆記

spring學習筆記

Bean Scopes (Bean的作用域)

Scope Description
singleton (Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototype Scopes a single bean definition to any number of object instances.
request Scopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext
.
session Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
application Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
websocket Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.
  1. 單例模式(Spring預設機制)

    <bean id="hello" class="com.kuang.pojo.Hello" c:age="18" c:name="青雲" scopes="singleton">	
    
  2. 原型模式(每一次從容器中get的時候,都會產生一個新的物件)

    <bean id="hello" class="com.kuang.pojo.Hello" c:age="18" c:name="雲" scopes="prototype">
    
  3. 其他模式request,session,application這些是在web 開發中使用

Bean的自動裝配

  • 自動裝配是Spring滿足bean依賴一種方式!

  • Spring會在上下文中自動尋找,並自動給bean裝配屬性!

    在Spring中有三種裝配的方式

    1. 在xml中顯示的配置
    2. 在java中顯示配置
    3. 隱式的自動裝配bean【重要】
  • ByName自動裝配
    byName:會自動在容器上下文中查詢,和自己物件set方法後面的名稱值對應的bean的id!

    <bean id="person" class="cn.kuang.pojo.Person" autowire="byName">
    <property name="name" value="程銘"/></bean>
    
  • ByType自動裝配
    會自動在容器上下文中查詢,和自己物件屬性型別相同的bean!

    <bean class="cn.kuang.pojo.Dog"/>
    <bean class="cn.kuang.pojo.Cat"/>
    <bean id="person" class="cn.kuang.pojo.Person" autowire="byType">
    <property name="name" value="程銘"/>
    </bean>
    

    小結

  • byname的時候,需要保證所有bean的id唯一,並且這個bean需要和自動注入的屬性的set方法名一致!

  • bytype的時候,需要保證所有bean的class唯一,並且這個備案需要和自動注入的屬性的型別一致!【同個型別的bean有多個是則不能用】

使用註解實現自動裝配

The introduction of annotation-based configuration raised the question of whether this approach is “better” than XML.

要使用註解須知:

  1. 匯入約束

  2. 配置註解的支援 開啟註解的支援context:annotation-config/ 【重要】

    • @Autowired可以配置在set方法上

    • 在屬性上配置@Autowired註解後可以連set方法都不需要,前提是自動裝配的屬性在這個IoC容器中,並且符合ByName

   <?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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           https://www.springframework.org/schema/beans/spring-beans.xsd
           http://www.springframework.org/schema/context
           https://www.springframework.org/schema/context/spring-context.xsd">

       <context:annotation-config/>
   </beans>

@Autowired

  • @Autowired是按型別自動轉配的,不支援id匹配。
  • 需要匯入 spring-aop的包!

測試:

1、將User類中的set方法去掉,使用@Autowired註解

public class User {   
	@Autowired   
	private Cat cat;   
	@Autowired   
	private Dog dog;   
	private String str;   
public Cat getCat() {       
	return cat;  
}   
public Dog getDog() {       
	return dog;  
}   
public String getStr() {       
	return str;  
}
}

2、此時配置檔案內容

<context:annotation-config/>
<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

3、測試,成功輸出結果!

【小狂神科普時間】

@Autowired(required=false) 說明:false,物件可以為null;true,物件必須存物件,不能為null。

//如果允許物件為null,設定required = false,預設為true
@Autowired(required = false)
private Cat cat;

@Qualifier

  • @Autowired是根據型別自動裝配的,加上@Qualifier則可以根據byName的方式自動裝配
  • @Qualifier不能單獨使用。

測試實驗步驟:

1、配置檔案修改內容,保證型別存在物件。且名字不為類的預設名字!

<bean id="dog1" class="com.kuang.pojo.Dog"/>
<bean id="dog2" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>

2、沒有加Qualifier測試,直接報錯

3、在屬性上新增Qualifier註解

@Autowired@Qualifier(value = "cat2")
private Cat cat;
@Autowired@Qualifier(value = "dog2")
private Dog dog;

測試,成功輸出!

@Resource

  • @Resource如有指定的name屬性,先按該屬性進行byName方式查詢裝配;
  • 其次再進行預設的byName方式進行裝配;
  • 如果以上都不成功,則按byType的方式自動裝配。
  • 都不成功,則報異常。

實體類:

public class User {   //如果允許物件為null,設定required = false,預設為true 
@Resource(name = "cat2")   
private Cat cat;   
@Resource   
private Dog dog;   
private String str;}

beans.xml

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>
<bean id="cat2" class="com.kuang.pojo.Cat"/>
<bean id="user" class="com.kuang.pojo.User"/>

測試:結果OK

配置檔案2:beans.xml , 刪掉cat2

<bean id="dog" class="com.kuang.pojo.Dog"/>
<bean id="cat1" class="com.kuang.pojo.Cat"/>

實體類上只保留註解

@Resource
private Cat cat;
@Resource
private Dog dog;

結果:OK

結論:先進行byName查詢,失敗;再進行byType查詢,成功。

小結

@Autowired與@Resource異同:

1、@Autowired與@Resource都可以用來裝配bean。都可以寫在欄位上,或寫在setter方法上。

2、@Autowired預設按型別裝配(屬於spring規範),預設情況下必須要求依賴物件必須存在,如果要允許null 值,可以設定它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結合@Qualifier註解進行使用

3、@Resource(屬於J2EE復返),預設按照名稱進行裝配,名稱可以通過name屬性進行指定。如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名進行按照名稱查詢,如果註解寫在setter方法上預設取屬性名進行裝配。當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。

它們的作用相同都是用註解方式注入物件,但執行順序不同。@Autowired先byType,@Resource先byName。

XML與註解比較

  • XML可以適用任何場景 ,結構清晰,維護方便
  • 註解不是自己提供的類使用不了,開發簡單方便

xml與註解整合開發 :推薦最佳實踐

  • xml管理Bean
  • 註解完成屬性注入
  • 使用過程中, 可以不用掃描,掃描是為了類上的註解
<context:annotation-config/>  

作用:

  • 進行註解驅動註冊,從而使註解生效
  • 用於啟用那些已經在spring容器裡註冊過的bean上面的註解,也就是顯示的向Spring註冊
  • 如果不掃描包,就需要手動配置bean
  • 如果不加註解驅動,則注入的值為null!