Spring——Bean

Bean的定義

  • 被稱作 bean 的對象是構(gòu)成應(yīng)用程序的支柱也是由 Spring IoC 容器管理的。bean 是一個被實例化田轧,組裝,并通過 Spring IoC 容器所管理的對象胆剧。這些 bean 是由用容器提供的配置元數(shù)據(jù)創(chuàng)建的饭玲,例如,在 XML 的表單中的 定義蓖宦。
  • bean 定義包含稱為配置元數(shù)據(jù)的信息齐婴,下述容器也需要知道配置元數(shù)據(jù):
    • 如何創(chuàng)建一個 bean
    • bean 的生命周期的詳細(xì)信息
    • bean 的依賴關(guān)系
  • 上述所有的配置元數(shù)據(jù)轉(zhuǎn)換成一組構(gòu)成每個 bean 定義的下列屬性。
    • class 這個屬性是強制性的稠茂,并且指定用來創(chuàng)建 bean 的 bean 類柠偶。
    • name 這個屬性指定唯一的 bean 標(biāo)識符。在基于 XML 的配置元數(shù)據(jù)中,你可以使用 ID 和/或 name 屬性來指定 bean 標(biāo)識符诱担。
    • scope 這個屬性指定由特定的 bean 定義創(chuàng)建的對象的作用域毡证,它將會在 bean 作用域的章節(jié)中進行討論。
    • constructor-arg 它是用來注入依賴關(guān)系的蔫仙,并會在接下來的章節(jié)中進行討論料睛。
    • properties 它是用來注入依賴關(guān)系的,并會在接下來的章節(jié)中進行討論匀哄。
    • autowiring mode 它是用來注入依賴關(guān)系的秦效,并會在接下來的章節(jié)中進行討論雏蛮。
    • lazy-initialization mode 延遲初始化的 bean 告訴 IoC 容器在它第一次被請求時涎嚼,而不是在啟動時去創(chuàng)建一個 bean 實例。
    • initialization 方法 在 bean 的所有必需的屬性被容器設(shè)置之后挑秉,調(diào)用回調(diào)方法法梯。它將會在 bean 的生命周期章節(jié)中進行討論。
    • destruction 方法 當(dāng)包含該 bean 的容器被銷毀時犀概,使用回調(diào)方法立哑。它將會在 bean 的生命周期章節(jié)中進行討論。

Spring 配置元數(shù)據(jù)

  • 基于 XML 的配置文件姻灶。
  • 基于注解的配置
  • 基于 Java 的配置

基于XML的配置

  • 在Spring框架中铛绰,依賴和服務(wù)需要在專門的配置文件來實現(xiàn),常用XML格式的配置文件
  • SpringXML配置的主要目的時候是使所有的Spring組件都可以用xml文件的形式來進行配置产喉。
    這意味著不會出現(xiàn)其他的Spring配置類型(比如聲明的方式或基于Java Class的配置方式)
  • Spring的XML配置方式是使用被Spring命名空間所支持的一系列XML標(biāo)簽來實現(xiàn)的捂掰。
  • Spring有以下主要的命名空間:context、beans曾沈、jdbc这嚣、tx、aop塞俱、mvc和aso姐帚。

基于注解的配置

  • 可以用注解的方式來替代XML方式的bean描述,
    可以將bean描述轉(zhuǎn)移到組件類的內(nèi)部障涯,只需要在相關(guān)類上罐旗、方法上或者字段聲明上使用注解即可。
  • 注解注入將會被容器在XML注入之前被處理唯蝶,所以后者會覆蓋掉前者對于同一個屬性的處理結(jié)果九秀。
  • 注解裝配在Spring中是默認(rèn)關(guān)閉的。所以需要在Spring文件中配置一下才能使用基于注解的裝配模式生棍。
  • 下面是幾種比較重要的注解類型:
    1颤霎、@Required:該注解應(yīng)用于設(shè)值方法。
    2、@Autowired:該注解應(yīng)用于有值設(shè)值方法友酱、非設(shè)值方法晴音、構(gòu)造方法和變量。
    3缔杉、@Qualifier:該注解和@Autowired注解搭配使用锤躁,用于消除特定bean自動裝配的歧義。
    4或详、JSR-250 Annotations:Spring支持基于JSR-250注解的以下注解,@Resource系羞、@PostConstruct和@PreDestroy。

基于Java的配置

  • Spring對Java配置的支持是由@Configuration注解和@Bean注解來實現(xiàn)的霸琴。由@Bean注解的方法將會實例化椒振、配置和初始化一個新對象,這個對象將由Spring的IoC容器來管理梧乘。
  • @Bean聲明所起到的作用與元素類似澎迎。
  • 被@Configuration所注解的類則表示這個類的主要目的是作為bean定義的資源。
  • 被@Configuration聲明的類可以通過在同一個類的內(nèi)部調(diào)用@bean方法來設(shè)置嵌入bean的依賴關(guān)系选调。
  • 如:
@Configuration
public class AppConfig{
    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

對于上面的@Beans配置文件相同的XML配置文件如下:

<beans>
    <bean id="myService" class="com.howtodoinjava.services.MyServiceImpl"/>
</beans>

上述配置方式的實例化方式如下:利用AnnotationConfigApplicationContext 類進行實例化

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    MyService myService = ctx.getBean(MyService.class);
    myService.doStuff();
}

要使用組件組建掃描夹供,僅需用@Configuration進行注解即可:

@Configuration
@ComponentScan(basePackages = "com.howtodoinjava")
public class AppConfig  {
    ...
}

Spring Bean的生命周期

  • Spring bean factory 負(fù)責(zé)管理在spring容器中被創(chuàng)建的bean的生命周期。Bean的生命周期由兩組回調(diào)(call back)方法組成仁堪。
    1哮洽、初始化之后調(diào)用的回調(diào)方法init-method。
    2弦聂、銷毀之前調(diào)用的回調(diào)方法destroy-method鸟辅。
    3、建議你不要使用 InitializingBean 或者 DisposableBean 的回調(diào)方法横浑,因為 XML 配置在命名方法上提供了極大的靈活性剔桨。

    • 創(chuàng)建:<bean name=”” class=”” 額外屬性>
    • 初始化:配置init-method 或 實現(xiàn)接口InitializingBean
    • 調(diào)用:context.getBean(),進行方法的調(diào)用
    • 銷毀:配置destroy-method 或 實現(xiàn)DisposableBean接口
  • Spring框架提供了以下四種方式來管理bean的生命周期事件:

    • InitializingBean和DisposableBean回調(diào)接口
    • 針對特殊行為的其他Aware接口
    • Bean配置文件中的Custom init()方法和destroy()方法
    • @PostConstruct和@PreDestroy注解方式
  • Bean加載流程
    (1)創(chuàng)建一個上下文context = createApplicationContext;
    (2)context中都會有一個BeanFactory(默認(rèn)是DefaultListableBeanFactory),在該類的子類類xmlBeanFactory中進行xml文件的解析;
    (3)在類XmlBeanDefinitionParser 中用Dom解析xml文件(DefaultXmlBeanDefinitionParser)徙融,解析xml文件中所有bean洒缀,并將bean放到BeanDefinitionHolder中,封裝成BeanDefinition欺冀;
    (4)再進行bean的注冊树绩,具體在BeanDefinitionReaderUtils類調(diào)用DefaultListableBeanFactory類的registerBeanDefinition進行bean的注冊,在這里用了一HashMap存放bean,其中用Beanname作為鍵值隐轩,其封裝好的beanDefinition作為值饺饭。還有用一個List存放所有的bean的名字。

怎樣定義類的作用域

通過bean 定義中的scope屬性來定義

Spring Bean的作用域

1职车、singleton:這種bean范圍是默認(rèn)的瘫俊,這種范圍確保不管接受到多少個請求鹊杖,每個容器中只有一個bean的實例,單例的模式由bean factory自身來維護扛芽。
2骂蓖、prototype:原形范圍與單例范圍相反,為每一個bean請求提供一個實例川尖。
3登下、request:在請求bean范圍內(nèi)會每一個來自客戶端的網(wǎng)絡(luò)請求創(chuàng)建一個實例,在請求完成以后,bean會失效并被垃圾回收器回收.
4、Session:與請求范圍類似叮喳,確保每個session中有一個bean的實例被芳,在session過期后,bean會隨之失效馍悟。
5畔濒、global-session:global-session和Portlet應(yīng)用相關(guān)。當(dāng)你的應(yīng)用部署在Portlet容器中工作時赋朦,它包含很多portlet篓冲。如果你想要聲明讓所有的portlet共用全局的存儲變量的話,那么這全局變量需要存儲在global-session中宠哄。

Spring inner beans

內(nèi)部bean可以用setter注入"屬性"構(gòu)造方法注入"構(gòu)造參數(shù)"的方式來實現(xiàn)。
比如嗤攻,在我們的應(yīng)用程序中毛嫉,一個Customer類引用了一個Person類,我們的要做的是創(chuàng)建一個Person的實例妇菱,然后在Customer內(nèi)部使用承粤。

public class Customer
{
    private Person person;

    //Setters and Getters
}

public class Person
{
    private String name;
    private String address;
    private int age;

    //Setters and Getters
}
<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">
  
    <bean id="CustomerBean" class="com.mkyong.common.Customer">
        <property name="person" ref="PersonBean" />
    </bean>
  
    <bean id="PersonBean" class="com.mkyong.common.Person">
        <property name="name" value="mkyong" />
        <property name="address" value="address1" />
        <property name="age" value="28" />
    </bean>
</beans>

變?yōu)椋?/p>

<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">
  
    <bean id="CustomerBean" class="com.mkyong.common.Customer">
        <property name="person">
            <bean class="com.mkyong.common.Person">
                <property name="name" value="mkyong" />
                <property name="address" value="address1" />
                <property name="age" value="28" />
            </bean>
        </property>
    </bean>
</beans>

構(gòu)造函數(shù)注入:

<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">
  
    <bean id="CustomerBean" class="com.mkyong.common.Customer">
        <constructor-arg>
            <bean class="com.mkyong.common.Person">
                <property name="name" value="mkyong" />
                <property name="address" value="address1" />
                <property name="age" value="28" />
            </bean>
        </constructor-arg>
    </bean>
</beans>

Spring框架中的單例Beans是線程安全的么

  • Spring框架并沒有對單例bean進行任何多線程的封裝處理。關(guān)于單例bean的線程安全和并發(fā)問題需要開發(fā)者自行去搞定闯团。
  • 實際上辛臊,大部分的Spring bean并沒有可變的狀態(tài)(比如Serview類和DAO類),所以在某種程度上說Spring的單例bean是線程安全的。如果你的bean有多種狀態(tài)的話(比如 View Model 對象)房交,就需要自行保證線程安全彻舰。
  • 最簡單的解決辦法就是將多態(tài)bean的作用域由"singleton"變更為"prototype"

什么是bean裝配?

裝配,或bean 裝配是指在Spring 容器中把bean組裝到一起候味,前提是容器需要知道bean的依賴關(guān)系刃唤,如何通過依賴注入來把它們裝配到一起。

什么是bean的自動裝配白群?

Spring 容器能夠自動裝配相互合作的bean尚胞,這意味著容器不需要<constructor-arg>和<property>配置,能通過Bean工廠自動處理bean之間的協(xié)作帜慢。

自動裝配的局限性是:

重寫: 你仍需用 <constructor-arg>和 <property> 配置來定義依賴笼裳,意味著總要重寫自動裝配唯卖。
基本數(shù)據(jù)類型:你不能自動裝配簡單的屬性,如基本數(shù)據(jù)類型躬柬,String字符串耐床,和類。
模糊特性:自動裝配不如顯式裝配精確楔脯,如果有可能撩轰,建議使用顯式裝配。

可以在Spring中注入一個null 和一個空字符串嗎昧廷?

可以堪嫂。

后置處理器BeanPostProcessor

  • BeanPostProcessor 接口定義回調(diào)方法,你可以實現(xiàn)該方法來提供自己的實例化邏輯木柬,依賴解析邏輯等皆串。你也可以在 Spring 容器通過插入一個或多個 BeanPostProcessor 的實現(xiàn)來完成實例化,配置和初始化一個bean之后實現(xiàn)一些自定義邏輯回調(diào)方法眉枕。

  • 可以配置多個 BeanPostProcesso r接口恶复,通過設(shè)置 BeanPostProcessor 實現(xiàn)的 Ordered 接口提供的 order 屬性來控制這些 BeanPostProcessor 接口的執(zhí)行順序。

  • BeanPostProcessor 可以對 bean(或?qū)ο螅嵗M行操作速挑,這意味著 Spring IoC 容器實例化一個 bean 實例谤牡,然后 BeanPostProcessor 接口進行它們的工作。

  • ApplicationContext 會自動檢測由 BeanPostProcessor 接口的實現(xiàn)定義的 bean姥宝,注冊這些 bean 為后置處理器翅萤,然后通過在容器中創(chuàng)建 bean,在適當(dāng)?shù)臅r候調(diào)用它腊满。

定義繼承套么、模板

  • bean 定義可以包含很多的配置信息,包括構(gòu)造函數(shù)的參數(shù)碳蛋,屬性值胚泌,容器的具體信息例如初始化方法,靜態(tài)工廠方法名肃弟,等等玷室。

  • 子 bean 的定義繼承父定義的配置數(shù)據(jù)。子定義可以根據(jù)需要重寫一些值愕乎,或者添加其他值阵苇。

  • Spring Bean 定義的繼承與 Java 類的繼承無關(guān),但是繼承的概念是一樣的感论。你可以定義一個父 bean 的定義作為模板和其他子 bean 就可以從父 bean 中繼承所需的配置绅项。
    如:

<bean id="helloWorld" class="com.tutorialspoint.HelloWorld">
<property name="message1" value="Hello World!"/>
<property name="message2" value="Hello Second World!"/>
</bean>

<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="helloWorld">
<property name="message1" value="Hello India!"/>
<property name="message3" value="Namaste India!"/>
</bean>

- 在定義一個 Bean 定義模板時,你不應(yīng)該指定類的屬性比肄,而應(yīng)該指定帶 true 值的抽象屬性

如下所示:
```xml
<bean id="beanTeamplate" abstract="true">
   <property name="message1" value="Hello World!"/>
   <property name="message2" value="Hello Second World!"/>
   <property name="message3" value="Namaste India!"/>
</bean>

<bean id="helloIndia" class="com.tutorialspoint.HelloIndia" parent="beanTeamplate">
   <property name="message1" value="Hello India!"/>
   <property name="message3" value="Namaste India!"/>
</bean>

基于構(gòu)造函數(shù)的依賴注入

構(gòu)造函數(shù)的參數(shù)在 bean 定義中的順序就是把這些參數(shù)提供給適當(dāng)?shù)臉?gòu)造函數(shù)的順序.

public class Foo {
   public Foo(Bar bar, Baz baz) {
      // ...
   }
}
<beans>
   <bean id="foo" class="x.y.Foo">
      <constructor-arg ref="bar"/>
      <constructor-arg ref="baz"/>
   </bean>

   <bean id="bar" class="x.y.Bar"/>
   <bean id="baz" class="x.y.Baz"/>
</beans>

傳遞給構(gòu)造函數(shù)不同類型的位置

public class Foo {
   public Foo(int year, String name) {
      // ...
   }
}
<beans>

   <bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg type="int" value="2001"/>
      <constructor-arg type="java.lang.String" value="Zara"/>
   </bean>

</beans>

最后并且也是最好的傳遞構(gòu)造函數(shù)參數(shù)的方式快耿,使用 index 屬性來顯式的指定構(gòu)造函數(shù)參數(shù)的索引囊陡。

<bean id="exampleBean" class="examples.ExampleBean">
      <constructor-arg index="0" value="2001"/>
      <constructor-arg index="1" value="Zara"/>
   </bean>

向一個對象傳遞一個引用,使用標(biāo)簽的 ref 屬性掀亥,直接傳遞值撞反,使用 value 屬性。

基于設(shè)值函數(shù)的依賴注入

  • 當(dāng)容器調(diào)用一個無參的構(gòu)造函數(shù)或一個無參的靜態(tài) factory 方法來初始化你的 bean 后搪花,通過容器在你的 bean 上調(diào)用設(shè)值函數(shù)遏片,基于設(shè)值函數(shù)的 DI 就完成了。
  • 有許多的設(shè)值函數(shù)方法撮竿,那么在 XML 配置文件中使用 p-namespace 是非常方便的吮便。
<bean id="john-classic" class="com.example.Person">
      <property name="name" value="John Doe"/>
      <property name="spouse" ref="jane"/>
   </bean>

   <bean name="jane" class="com.example.Person">
      <property name="name" value="John Doe"/>
   </bean>

使用p-namespace:

<bean id="john-classic" class="com.example.Person"
      p:name="John Doe"
      p:spouse-ref="jane"/>
   </bean>

   <bean name="jane" class="com.example.Person"
      p:name="John Doe"/>
   </bean>

注入集合

Spring 提供了四種類型的集合的配置元素:List、Set幢踏、Map 和 Properties
如:

public class JavaCollection {
   List addressList;
   Set  addressSet;
   Map  addressMap;
   Properties addressProp;
   // a setter method to set List
   public void setAddressList(List addressList) {
      this.addressList = addressList;
   }
   // prints and returns all the elements of the list.
   public List getAddressList() {
      System.out.println("List Elements :"  + addressList);
      return addressList;
   }
   // a setter method to set Set
   public void setAddressSet(Set addressSet) {
      this.addressSet = addressSet;
   }
   // prints and returns all the elements of the Set.
   public Set getAddressSet() {
      System.out.println("Set Elements :"  + addressSet);
      return addressSet;
   }
   // a setter method to set Map
   public void setAddressMap(Map addressMap) {
      this.addressMap = addressMap;
   }  
   // prints and returns all the elements of the Map.
   public Map getAddressMap() {
      System.out.println("Map Elements :"  + addressMap);
      return addressMap;
   }
   // a setter method to set Property
   public void setAddressProp(Properties addressProp) {
      this.addressProp = addressProp;
   } 
   // prints and returns all the elements of the Property.
   public Properties getAddressProp() {
      System.out.println("Property Elements :"  + addressProp);
      return addressProp;
   }
}

xml 配置:

   <!-- Definition for javaCollection -->
   <bean id="javaCollection" class="com.tutorialspoint.JavaCollection">

      <!-- results in a setAddressList(java.util.List) call -->
      <property name="addressList">
         <list>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
         </list>
      </property>

      <!-- results in a setAddressSet(java.util.Set) call -->
      <property name="addressSet">
         <set>
            <value>INDIA</value>
            <value>Pakistan</value>
            <value>USA</value>
            <value>USA</value>
        </set>
      </property>

      <!-- results in a setAddressMap(java.util.Map) call -->
      <property name="addressMap">
         <map>
            <entry key="1" value="INDIA"/>
            <entry key="2" value="Pakistan"/>
            <entry key="3" value="USA"/>
            <entry key="4" value="USA"/>
         </map>
      </property>

      <!-- results in a setAddressProp(java.util.Properties) call -->
      <property name="addressProp">
         <props>
            <prop key="one">INDIA</prop>
            <prop key="two">Pakistan</prop>
            <prop key="three">USA</prop>
            <prop key="four">USA</prop>
         </props>
      </property>

   </bean>

注入 Bean 引用

下面的 Bean 定義將幫助你理解如何注入 bean 的引用作為集合的元素髓需。甚至你可以將引用和值混合在一起,了使用 bean 定義房蝉,你需要定義相應(yīng)的 setter 方法僚匆,它們應(yīng)該也能夠是用這種方式來處理引用。如下所示:

<!-- Bean Definition to handle references and values -->
   <bean id="..." class="...">

      <!-- Passing bean reference  for java.util.List -->
      <property name="addressList">
         <list>
            <ref bean="address1"/>
            <ref bean="address2"/>
            <value>Pakistan</value>
         </list>
      </property>

      <!-- Passing bean reference  for java.util.Set -->
      <property name="addressSet">
         <set>
            <ref bean="address1"/>
            <ref bean="address2"/>
            <value>Pakistan</value>
         </set>
      </property>

      <!-- Passing bean reference  for java.util.Map -->
      <property name="addressMap">
         <map>
            <entry key="one" value="INDIA"/>
            <entry key ="two" value-ref="address1"/>
            <entry key ="three" value-ref="address2"/>
         </map>
      </property>

   </bean>

注入 null 和空字符串的值

<bean id="..." class="exampleBean">
   <property name="email" value=""/>
</bean>

<bean id="..." class="exampleBean">
   <property name="email"><null/></property>
</bean>

Bean自動裝配

有這么一個Bean

public class TextEditor {
   private SpellChecker spellChecker;
   private String name;
   public void setSpellChecker( SpellChecker spellChecker ) {
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

public class SpellChecker {
   public SpellChecker() {
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   }   
}

自動裝配 ‘byName’

這種模式由屬性名稱指定自動裝配搭幻。Spring 容器看作 beans咧擂,在 XML 配置文件中 beans 的 auto-wire 屬性設(shè)置為 byName。然后粗卜,它嘗試將它的屬性與配置文件中定義為相同名稱的 beans 進行匹配和連接屋确。如果找到匹配項,它將注入這些 beans续扔,否則,它將拋出異常焕数。

例如纱昧,在配置文件中,如果一個 bean 定義設(shè)置為自動裝配 byName堡赔,并且它包含 spellChecker 屬性(即识脆,它有一個 setSpellChecker(...) 方法),那么 Spring 就會查找定義名為 spellChecker 的 bean善已,并且用它來設(shè)置這個屬性灼捂。你仍然可以使用 <property> 標(biāo)簽連接其余的屬性。下面的例子將說明這個概念换团。

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor" 
      autowire="byName">
      <property name="name" value="Generic Text Editor" />
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

自動裝配 ‘byType’

這種模式由屬性類型指定自動裝配悉稠。Spring 容器看作 beans,在 XML 配置文件中 beans 的 autowire 屬性設(shè)置為 byType艘包。然后的猛,如果它的 type 恰好與配置文件中 beans 名稱中的一個相匹配耀盗,它將嘗試匹配和連接它的屬性。如果找到匹配項卦尊,它將注入這些 beans叛拷,否則,它將拋出異常岂却。

例如忿薇,在配置文件中,如果一個 bean 定義設(shè)置為自動裝配 byType躏哩,并且它包含 SpellChecker 類型的 spellChecker 屬性署浩,那么 Spring 就會查找定義名為 SpellChecker 的 bean,并且用它來設(shè)置這個屬性震庭。你仍然可以使用 <property> 標(biāo)簽連接其余屬性瑰抵。下面的例子將說明這個概念,你會發(fā)現(xiàn)和上面的例子沒有什么區(qū)別器联,除了 XML 配置文件已經(jīng)被改變二汛。

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor" 
      autowire="byType">
      <property name="name" value="Generic Text Editor" />
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="SpellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

由構(gòu)造函數(shù)自動裝配

這種模式與 byType 非常相似,但它應(yīng)用于構(gòu)造器參數(shù)拨拓。Spring 容器看作 beans肴颊,在 XML 配置文件中 beans 的 autowire 屬性設(shè)置為 constructor。然后渣磷,它嘗試把它的構(gòu)造函數(shù)的參數(shù)與配置文件中 beans 名稱中的一個進行匹配和連線婿着。如果找到匹配項,它會注入這些 bean醋界,否則竟宋,它會拋出異常。

例如形纺,在配置文件中丘侠,如果一個 bean 定義設(shè)置為通過構(gòu)造函數(shù)自動裝配,而且它有一個帶有 SpellChecker 類型的參數(shù)之一的構(gòu)造函數(shù)逐样,那么 Spring 就會查找定義名為 SpellChecker 的 bean蜗字,并用它來設(shè)置構(gòu)造函數(shù)的參數(shù)。你仍然可以使用 <constructor-arg> 標(biāo)簽連接其余屬性脂新。下面的例子將說明這個概念挪捕。

public class TextEditor {
   private SpellChecker spellChecker;
   private String name;
   public TextEditor( SpellChecker spellChecker, String name ) {
      this.spellChecker = spellChecker;
      this.name = name;
   }
   public SpellChecker getSpellChecker() {
      return spellChecker;
   }
   public String getName() {
      return name;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}
   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor" 
      autowire="constructor">
      <constructor-arg value="Generic Text Editor"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="SpellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市争便,隨后出現(xiàn)的幾起案子级零,更是在濱河造成了極大的恐慌,老刑警劉巖始花,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件妄讯,死亡現(xiàn)場離奇詭異孩锡,居然都是意外死亡,警方通過查閱死者的電腦和手機亥贸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門躬窜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人炕置,你說我怎么就攤上這事荣挨。” “怎么了朴摊?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵默垄,是天一觀的道長。 經(jīng)常有香客問我甚纲,道長口锭,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上颜说,老公的妹妹穿的比我還像新娘。我一直安慰自己荆隘,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布赴背。 她就那樣靜靜地躺著椰拒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凰荚。 梳的紋絲不亂的頭發(fā)上燃观,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天,我揣著相機與錄音便瑟,去河邊找鬼仪壮。 笑死,一個胖子當(dāng)著我的面吹牛胳徽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播爽彤,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼养盗,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了适篙?” 一聲冷哼從身側(cè)響起往核,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嚷节,沒想到半個月后聂儒,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體虎锚,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年衩婚,在試婚紗的時候發(fā)現(xiàn)自己被綠了窜护。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡非春,死狀恐怖柱徙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情奇昙,我是刑警寧澤护侮,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站储耐,受9級特大地震影響羊初,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜什湘,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一长赞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧禽炬,春花似錦涧卵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至热幔,卻和暖如春乐设,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背绎巨。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工近尚, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人场勤。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓戈锻,卻偏偏與公主長得像,于是被迫代替她去往敵國和親和媳。 傳聞我的和親對象是個殘疾皇子格遭,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容