1. 程式人生 > 實用技巧 >Spring基礎

Spring基礎

Spring IoC 容器

IoC:Inversion of Control -->控制反轉
控制反轉:是通過描述(可以是xml或者註解)並通過第三方(springIOC容器)產生或獲取特定物件的方式;
DI:Dependency Injection -->依賴注入 依賴注入:依賴指的是一種關係,如:類A需要類B的引用,而依賴注入指的是類A要獲取類B的物件是通過外部傳遞的方式,而不是直接new一個類B的例項。
通俗的說:控制反轉和依賴注入都是從第三方獲取物件而不是直接new一個物件,兩者是一個意思

Spring 提供了以下兩種不同型別的容器。

序號容器 & 描述
1Spring BeanFactory 容器

它是最簡單的容器,給 DI 提供了基本的支援,它用 org.springframework.beans.factory.BeanFactory 介面來定義。BeanFactory 或者相關的介面,如 BeanFactoryAware,InitializingBean,DisposableBean,在 Spring 中仍然存在具有大量的與 Spring 整合的第三方框架的反向相容性的目的。

2Spring ApplicationContext 容器

該容器添加了更多的企業特定的功能,例如從一個屬性檔案中解析文字資訊的能力,釋出應用程式事件給感興趣的事件監聽器的能力。該容器是由 org.springframework.context.ApplicationContext 介面定義。

ApplicationContext 容器包括 BeanFactory 容器的所有功能,所以通常建議超過 BeanFactory。BeanFactory 仍然可以用於輕量級的應用程式,如移動裝置或基於 applet 的應用程式,其中它的資料量和速度是顯著。


Spring Bean

被稱作 bean 的物件是構成應用程式的支柱也是由 Spring IoC 容器管理的。bean 是一個被例項化,組裝,並通過 Spring IoC 容器所管理的物件。這些 bean 是由用容器提供的配置元資料建立的,例如,在 XML 的表單中的 定義。

bean 定義包含稱為配置元資料的資訊,下述容器也需要知道配置元資料:

  • 如何建立一個 bean
  • bean 的生命週期的詳細資訊
  • bean 的依賴關係

上述所有的配置元資料轉換成一組構成每個 bean 定義的下列屬性。

屬性描述
class這個屬性是強制性的,並且指定用來建立 bean 的 bean 類。
name這個屬性指定唯一的 bean 識別符號。在基於 XML 的配置元資料中,你可以使用 ID 和/或 name 屬性來指定 bean 識別符號。
scope這個屬性指定由特定的 bean 定義建立的物件的作用域,它將會在 bean 作用域的章節中進行討論。
constructor-arg它是用來注入依賴關係的,並會在接下來的章節中進行討論。
properties它是用來注入依賴關係的,並會在接下來的章節中進行討論。
autowiring mode它是用來注入依賴關係的,並會在接下來的章節中進行討論。
lazy-initialization mode延遲初始化的 bean 告訴 IoC 容器在它第一次被請求時,而不是在啟動時去建立一個 bean 例項。
initialization 方法在 bean 的所有必需的屬性被容器設定之後,呼叫回撥方法。它將會在 bean 的生命週期章節中進行討論。
destruction 方法當包含該 bean 的容器被銷燬時,使用回撥方法。它將會在 bean 的生命週期章節中進行討論。

Bean 與 Spring 容器的關係

下圖表達了Bean 與 Spring 容器之間的關係:



作用域--scope

作用域描述
singleton

在springIoC容器僅存在一個Bean例項,Bean以單例方式存在,預設值

prototype每次從容器中呼叫Bean時,都返回一個新的例項,即每次呼叫getBean()時,相當於執行newXxxBean()
request每次HTTP請求都會建立一個新的Bean,該作用域僅適用於WebApplicationContext環境
session同一個HTTP Session共享一個Bean,不同Session使用不同的Bean,僅適用於WebApplicationContext環境
global-session一般用於Portlet應用環境,該運用域僅適用於WebApplicationContext環境

生命週期

init-method屬性:在例項化 bean 時,立即呼叫該方法。
destroy-method屬性:只有從容器中移除 bean 之後,才能呼叫該方法。
Beans.xml

<bean id="helloWorld" class="com.demo.HelloWorld" init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World!"/>
</bean>
12345
package com.demo;

public class HelloWorld {
    private String message;

    public void init(){
        System.out.println("welcome to use Helloworld..");
    }

    public void destroy(){
        System.out.println("[Helloworld]:say you again..");
    }
    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

}
123456789101112131415161718192021

package com.demo;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        // 你需要註冊一個在 AbstractApplicationContext 類中宣告的關閉 hook 的 registerShutdownHook() 方法。
        // 它將確保正常關閉,並且呼叫相關的 destroy 方法。
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        String msg = obj.getMessage();
        System.out.println("[Your Msg]:" + msg);
        context.registerShutdownHook();   // 可以理解為關閉IoC容器的方法
    }
}

welcome to use Helloworld..
[Your Msg]:Hello World!
[Helloworld]:say you again..
123456789101112131415161718192021


Spring Bean 後置處理器

Bean 後置處理器允許在呼叫始化方法前後對 Bean 進行自定義的處理(eg:注入處理一些統一的屬性,而不用在每個bean中注入/日誌列印等)。

BeanPostProcessor 介面定義回撥方法,你可以實現該方法來提供自己的例項化邏輯,依賴解析邏輯等。你也可以在 Spring 容器通過插入一個或多個 BeanPostProcessor 的實現來完成例項化,配置和初始化一個bean之後實現一些自定義邏輯回撥方法。

你可以配置多個 BeanPostProcessor 介面,通過設定 BeanPostProcessor 實現的 Ordered 介面提供的 order 屬性來控制這些 BeanPostProcessor 介面的執行順序。

BeanPostProcessor 可以對 bean(或物件)例項進行操作,這意味著 Spring IoC 容器例項化一個 bean 例項,然後 BeanPostProcessor 介面進行它們的工作

ApplicationContext 會自動檢測由 BeanPostProcessor 介面的實現定義的 bean,註冊這些 bean 為後置處理器,然後通過在容器中建立 bean,在適當的時候呼叫它。

備註:

通俗點講就是在bean初始化函式(init-method指定的方法)前後執行實現BeanPostProcessor介面的兩個方法:

postProcessBeforeInitialization

postProcessAfterInitialization
package com.demo;

public class HelloWorld {
    private String message;

    public void init(){
        System.out.println("welcome to use Helloworld..");
    }

    public void destroy(){
        System.out.println("[Helloworld]:say you again..");
    }
    public void setMessage(String message) {
        this.message = message;
    }

    public String getMessage() {
        return message;
    }

}
123456789101112131415161718192021
package com.demo;

public class HelloSpring {
    private String springdata;

    public void init(){
        System.out.println("welcome to use HelloSpring..");
    }

    public void destroy(){
        System.out.println("[HelloSpring]:say you again..");
    }

    public void setSpringdata(String springdata) {
        this.springdata = springdata;
    }

    public String getSpringdata() {
        return springdata;
    }
}
123456789101112131415161718192021
package com.demo;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class InitHelloworld implements BeanPostProcessor {

    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("BeforeInitialization:"+beanName);
        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("AfterInitialization:"+beanName);
        return bean;
    }
}
1234567891011121314151617
package com.demo;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {

    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
        String msg = obj.getMessage();
        System.out.println("[Your Msg]:" + msg);
        HelloSpring objsp = (HelloSpring) context.getBean("helloSpring");
        msg = objsp.getSpringdata();
        System.out.println("[Your Msg]:" + msg);
        context.registerShutdownHook();
    }
}
12345678910111213141516171819
<?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-3.0.xsd">

    <bean id="helloWorld" class="com.demo.HelloWorld" init-method="init" destroy-method="destroy">
        <property name="message" value="Hello World!"/>
    </bean>

    <bean id="helloSpring" class="com.demo.HelloSpring" init-method="init" destroy-method="destroy">
        <property name="springdata" value="Hello Spring!"/>
    </bean>

    <bean id="initHelloworld" class="com.demo.InitHelloworld" />

</beans>
123456789101112131415161718執行main方法列印結果如下:
BeforeInitialization:helloWorld
welcome to use Helloworld..
AfterInitialization:helloWorld
BeforeInitialization:helloSpring
welcome to use HelloSpring..
AfterInitialization:helloSpring
[Your Msg]:Hello World!
[Your Msg]:Hello Spring!
[HelloSpring]:say you again..
[Helloworld]:say you again..
12345678910


Spring Bean 的繼承

  • bean 定義可以包含很多的配置資訊,包括建構函式的引數,屬性值,容器的具體資訊例如初始化方法,靜態工廠方法名,等等。
  • 子 bean 的定義繼承父定義的配置資料。子定義可以根據需要重寫一些值,或者新增其他值。
  • Spring Bean 定義的繼承與 Java 類的繼承無關,但是繼承的概念是一樣的。你可以定義一個父 bean 的定義作為模板和其他子 bean 就可以從父 bean 中繼承所需的配置。
示例:Beans.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-3.0.xsd">
    
	<!--僅僅作為一個模板,不和任何類繫結,且宣告為抽象bean-->
    <bean id="module" abstract="true">
        <property name="msg0" value="this is msg0"/>
        <property name="msg1" value="this is msg1"/>
    </bean>
    
	<!--helloWorldA 繼承於module-->
    <bean id="helloWorldA" class="com.v20191215.HelloWorldA" parent="module">
        <property name="msg1" value="hello msg1"/>
        <property name="msg2" value="hello msg2"/>
    </bean>
</beans>
12345678910111213141516171819HelloworldA.java
package com.v20191215;

public class HelloWorldA {
    private String msg0;    // 雖然bean中定義沒有msg0,但是bean的父類中有該屬性,被繼承過來了
    private String msg1;
    private String msg2;
 
    public String getMsg0() {
        System.out.println(msg0);
        return msg0;
    }

    public String getMsg1() {
        System.out.println(msg1);
        return msg1;
    }

    public String getMsg2() {
        System.out.println(msg2);
        return msg2;
    }

    public void setMsg0(String msg0) {
        this.msg0 = msg0;
    }

    public void setMsg1(String msg1) {
        this.msg1 = msg1;
    }

    public void setMsg2(String msg2) {
        this.msg2 = msg2;
    }
}
12345678910111213141516171819202122232425262728293031323334MainApp.java
package com.v20191215;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        HelloWorldA obj = (HelloWorldA) context.getBean("helloWorldA");
        obj.getMsg0();
        obj.getMsg1();
        obj.getMsg2();
    }
}

/**
*輸出結果如下:
*this is msg0
*hello msg1
*hello msg2
*
*Process finished with exit code 0
*/
1234567891011121314151617181920212223


Spring 依賴注入

依賴注入:依賴指的是一種關係,如:類A需要類B的引用,而依賴注入指的是類A要獲取類B的物件是通過外部傳遞的方式,而不是直接new一個類B的例項。
依賴注入的兩種方式
  • 基於建構函式實現依賴注入
  • 基於設定方法(setter)實現依賴注入


基於建構函式實現依賴注入

eg:一個文字編輯類需要依賴一個拼寫檢查類實現相關的功能。TextEditor.java
package com.v20191215;

public class TextEditor {
    private SpellChecker spellChecker;

    public TextEditor(SpellChecker spellChecker){
        this.spellChecker = spellChecker;
    }
    
    public void  spellChecker() {
        spellChecker.checkSpelling();
    }

    public SpellChecker getSpellChecker() {
        return spellChecker;
    }

    public void setSpellChecker(SpellChecker spellChecker) {
        this.spellChecker = spellChecker;
    }
}
123456789101112131415161718192021SpellChecker.java
package com.v20191215;

import static com.utils.Print.println;
public class SpellChecker {

    public void SpellChecker(){
        println("SpellChecker constructor...");
    }

    public void checkSpelling(){
        println("use checkSpelling ");
    }
}
1234567891011121314MainApp.java
package com.v20191215;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;


public class MainApp {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        TextEditor textEditor = (TextEditor) context.getBean("textEditor");
        textEditor.spellChecker();
    }
}
1234567891011121314Beans.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-3.0.xsd">

    <bean id="testEditor" class="com.v20191215.TextEditor" >
        <constructor-arg  ref="spellChecker"/>                <!--通過構造器引數注入bean-->
    </bean>

    <bean id="spellChecker" class="com.v20191215.SpellChecker" />
</beans>
12345678910111213

基於設定方法(setter)實現依賴注入

TextEditor.java去除構造器,SpellChecker類和MainApp類不變,修改Beans.xml配置檔案
package com.v20191215;

import static com.utils.Print.println;
public class TextEditor {

    private SpellChecker spellChecker;

    public void  spellChecker() {
        spellChecker.checkSpelling();
    }

    public SpellChecker getSpellChecker() {
        return spellChecker;
    }

    public void setSpellChecker(SpellChecker spellChecker) {
        this.spellChecker = spellChecker;
    }
}
1234567891011121314151617181920Beans.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-3.0.xsd">

    <bean id="testEditor" class="com.v20191215.TextEditor" >
        <property name="spellChecker"  ref="spellChecker"/>   <!--通過set傳參的方式注入依賴-->
    </bean>

    <bean id="spellChecker" class="com.v20191215.SpellChecker" />
</beans>
12345678910111213MainApp.java輸出:
use checkSpelling 
1

注入內部Beans

內部Bean類比於java的內部類上述所有類均不改變,只修改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-3.0.xsd">

    <bean id="testEditor" class="com.v20191215.TextEditor" >
        <property name="spellChecker">
            <bean id="spellChecker" class="com.v20191215.SpellChecker" />
        </property>
    </bean>
</beans>
12345678910111213MainApp.java輸出:
use checkSpelling 
1

集合的注入

使用 value 屬性來配置基本資料型別使用<property>標籤的 ref 屬性來配置物件的引用也可以通過一下四種標籤注入集合:
  • <list> value值可以重複
  • <set> value值不可以重複
  • <map> 它可以用來注入名稱-值對的集合,其中名稱和值可以是任何型別
  • <props> 它可以用來注入名稱-值對的集合,其中名稱和值都是字串型別。
eg:Address.java
package com.v20191215;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import static com.utils.Print.println;

public class Address {
    private List addressList;
    private Set addressSet;
    private Map  addressMap;
    private Properties addressProp;

    public List getAddressList() {
        println("List: "+addressList);
        return addressList;
    }

    public void setAddressList(List addressList) {
        this.addressList = addressList;
    }

    public Set getAddressSet() {
        println("Set: "+addressSet);
        return addressSet;
    }

    public void setAddressSet(Set addressSet) {
        this.addressSet = addressSet;
    }

    public Map getAddressMap() {
        println("Map: "+addressMap);
        return addressMap;
    }

    public void setAddressMap(Map addressMap) {
        this.addressMap = addressMap;
    }

    public Properties getAddressProp() {
        println("Prop: "+addressProp);
        return addressProp;
    }

    public void setAddressProp(Properties addresProp) {
        this.addressProp = addresProp;
    }

}
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152People.java
package com.v20191215;

public class People {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name;

}
123456789101112131415Beans.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-3.0.xsd">

    <bean id="address" class="com.v20191215.Address">
        <!--        注入list-->
        <property name="addressList">
            <list>
                <value>INDIA</value>
                <value>Pakistan</value>
                <value>USA</value>
                <value>USA</value>
            </list>
        </property>
        <property name="addressSet">
            <set>
                <value>INDIA</value>
                <value>Pakistan</value>
                <value>USA</value>
                <value>USA</value>
            </set>
        </property>
        <property name="addressMap">
            <map>
                <entry key="1" value="INDIA"/>     <!--   注入基礎值-->
                <entry key="2" value="Pakistan"/>
                <entry key="3" value="USA"/>
                <entry key="4" value-ref="people"/>  <!-- 注入物件-->
            </map>
        </property>

        <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 id="people" class="com.v20191215.People">
        <property name="name" value="fireMan"/>
    </bean>
</beans>
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849MainApp.java
package com.v20191215;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        AbstractApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
        Address address = (Address) context.getBean("address");
        address.getAddressList();
        address.getAddressSet();
        address.getAddressMap();
        address.getAddressProp();
    }
}
/**
 * 輸出結果:
 * List: [INDIA, Pakistan, USA, USA]
 * Set: [INDIA, Pakistan, USA]
 * Map: {1=INDIA, 2=Pakistan, 3=USA, 4=com.v20191215.People@148080bb}   // 可以看出第四個值是物件的引用被成功的注入
 * Prop: {two=Pakistan, one=INDIA, three=USA, four=USA}
 */
12345678910111213141516171819202122

Spring Beans 自動裝配

使用<bean>元素來宣告 bean通過使用 XML 配置檔案中的<constructor-arg><property>元素來注入 依賴,也可以使用自動裝配進行依賴的注入
使用<bean>元素的 autowire 屬性為一個 bean 定義指定自動裝配模式。
模式描述
no這是預設的設定,它意味著沒有自動裝配。
byName由屬性名自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byName。
然後嘗試匹配,並且將它的屬性與在配置檔案中被定義為相同名稱的 beans 的屬性進行連線。
byType由屬性資料型別自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byType。
然後如果它的型別匹配配置檔案中的一個確切的 bean 名稱,它將嘗試匹配和連線屬性的型別。
如果存在不止一個這樣的 bean,則一個致命的異常將會被丟擲。
constructor類似於 byType,但該型別適用於建構函式引數型別。
如果在容器中沒有一個建構函式引數型別的 bean,則一個致命錯誤將會發生。
autodetectSpring首先嚐試通過 constructor 使用自動裝配來連線,如果它不執行,Spring 嘗試通過 byType 來自動裝配。

eg:

正常情況下的配置檔案:

<?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-3.0.xsd">

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

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

</beans>
123456789101112131415161718使用自動裝配 “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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- 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>

</beans>
1234567891011121314151617使用自動裝配 “byType”:
<?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-3.0.xsd">

   <!-- 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>

</beans>
123456789101112131415161718使用自動裝配 “by constructor”:
<?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-3.0.xsd">

   <!-- 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>

</beans>
123456789101112131415161718


Spring 基於註解的注入

從Spring2.5開始可以通過註解配置依賴進行注入,你可以使用相關類,方法或欄位宣告的註解,將 bean 配置移動到元件類本身。
序號註解 & 描述
1@Required

@Required 註解應用於 bean 屬性的 setter 方法。

2@Autowired

@Autowired 註解可以應用到 bean 屬性的 setter 方法,非 setter 方法,建構函式和屬性。

3@Qualifier

通過指定確切的將被連線的 bean,@Autowired 和 @Qualifier 註解可以用來刪除混亂。

4JSR-250 Annotations

Spring 支援 JSR-250 的基礎的註解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 註解。


@Required

應用於 bean 屬性的 setter 方法,它表明受影響的 bean 屬性在 XML 配置檔案中必須進行顯示配置,否則容器就會丟擲一個 BeanInitializationException 異常。
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Required;
public class Student {
   private Integer age;
   private String name;
   @Required
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }
   @Required
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
}
1234567891011121314151617181920
<?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
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>
1234567891011121314151617
package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
      Student student = (Student) context.getBean("student");
      System.out.println("Name : " + student.getName() );
      System.out.println("Age : " + student.getAge() );
   }
}
1234567891011


@Autowired


package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
   @Autowired
   private SpellChecker spellChecker;
   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }  
   public SpellChecker getSpellChecker( ){
      return spellChecker;
   }  
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}
123456789101112131415
<?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
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
   </bean>

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

</beans>
123456789101112131415161718192021

@Qualifier

可能會有這樣一種情況,當你建立多個具有相同型別的 bean 時,並且想要用一個屬性只為它們其中的一個進行裝配,在這種情況下,你可以使用 @Qualifier@Autowired通過指定哪一個真正的 bean 將會被裝配來消除混亂。
package com.tutorialspoint;
import org.springframework.beans.factory.annotation.Autowired;
public class TextEditor {
   @Autowired
   @Qualifier("spellChecker1")
   private SpellChecker spellChecker;
   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }  
   public SpellChecker getSpellChecker( ){
      return spellChecker;
   }  
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}
12345678910111213141516

Spring AOP


Spring 對AspectJ的支援


end