Java學習筆記(10)Spring Bean配置
Spring Beans自動裝配
Beans自動裝配:
Spring 容器可以在不使用<constructor-arg>
和<property>
元素的情況下自動裝配相互協作的 bean 之間的關係,這有助於減少編寫一個大的基於 Spring 的應用程式的 XML 配置的數量。
自動裝配模式:
下列自動裝配模式,它們可用於指示 Spring 容器為來使用自動裝配進行依賴注入。你可以使用<bean>
元素的 autowire 屬性為一個 bean 定義指定自動裝配模式。
模式 | 描述 |
---|---|
no | 這是預設的設定,它意味著沒有自動裝配,你應該使用顯式的bean引用來連線。你不用為了連線做特殊的事。 |
由屬性名自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byName。然後嘗試匹配,並且將它的屬性與在配置檔案中被定義為相同名稱的 beans 的屬性進行連線。 | |
由屬性資料型別自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byType。然後如果它的型別匹配配置檔案中的一個確切的 bean 名稱,它將嘗試匹配和連線屬性的型別。如果存在不止一個這樣的 bean,則一個致命的異常將會被丟擲。 | |
類似於 byType,但該型別適用於建構函式引數型別。如果在容器中沒有一個建構函式引數型別的 bean,則一個致命錯誤將會發生。 | |
autodetect | Spring首先嚐試通過 constructor 使用自動裝配來連線,如果它不執行,Spring 嘗試通過 byType 來自動裝配。 |
可以使用 byType 或者 constructor 自動裝配模式來連線陣列和其他型別的集合。
自動裝配的侷限性:
當自動裝配始終在同一個專案中使用時,它的效果最好。如果通常不使用自動裝配,它可能會使開發人員混淆的使用它來連線只有一個或兩個 bean 定義。不過,自動裝配可以顯著減少需要指定的屬性或構造器引數,但你應該在使用它們之前考慮到自動裝配的侷限性和缺點。
限制 | 描述 |
---|---|
重寫的可能性 | 你可以使用總是重寫自動裝配的 和 設定來指定依賴關係。 |
原始資料型別 | 你不能自動裝配所謂的簡單型別包括基本型別,字串和類。 |
混亂的本質 | 自動裝配不如顯式裝配精確,所以如果可能的話儘可能使用顯式裝配。 |
Spring自動裝配”byName”:
這種模式由屬性名稱指定自動裝配。Spring 容器看作 beans,在 XML 配置檔案中 beans 的 auto-wire 屬性設定為 byName。然後,它嘗試將它的屬性與配置檔案中定義為相同名稱的 beans 進行匹配和連線。如果找到匹配項,它將注入這些 beans,否則,它將丟擲異常。
例如,在配置檔案中,如果一個 bean 定義設定為自動裝配 byName,並且它包含 spellChecker 屬性(即,它有一個 setSpellChecker(…) 方法),那麼 Spring 就會查詢定義名為 spellChecker 的 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">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="autowire.TextEditor">
<property name="spellChecker" ref="spellChecker" />
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="autowire.SpellChecker">
</bean>
</beans>
但是,如果你要使用自動裝配 “byName”,那麼你的 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">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="autowire.TextEditor"
autowire="byName">
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="autowire.SpellChecker">
</bean>
</beans>
Spring自動裝配”byType”:
這種模式由屬性型別指定自動裝配。Spring 容器看作 beans,在 XML 配置檔案中 beans 的 autowire 屬性設定為 byType。然後,如果它的 type 恰好與配置檔案中 beans 名稱中的一個相匹配,它將嘗試匹配和連線它的屬性。如果找到匹配項,它將注入這些 beans,否則,它將丟擲異常。
例如,在配置檔案中,如果一個 bean 定義設定為自動裝配 byType,並且它包含 SpellChecker 型別的 spellChecker 屬性,那麼 Spring 就會查詢定義名為 SpellChecker 的 bean,並且用它來設定這個屬性。你仍然可以使用
<?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="autowire.TextEditor">
<property name="spellChecker" ref="spellChecker" />
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="autowire.SpellChecker">
</bean>
</beans>
但是,如果你要使用自動裝配 “byType”,那麼你的 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">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="autowire.TextEditor"
autowire="byType">
<property name="name" value="Generic Text Editor" />
</bean>
<!-- Definition for spellChecker bean -->
<bean id="SpellChecker" class="autowire.SpellChecker">
</bean>
</beans>
Spring由建構函式自動裝配:
這種模式與 byType 非常相似,但它應用於構造器引數。Spring 容器看作 beans,在 XML 配置檔案中 beans 的 autowire 屬性設定為 constructor。然後,它嘗試把它的建構函式的引數與配置檔案中 beans 名稱中的一個進行匹配和連線。如果找到匹配項,它會注入這些 bean,否則,它會丟擲異常。
例如,在配置檔案中,如果一個 bean 定義設定為通過建構函式自動裝配,而且它有一個帶有 SpellChecker型別的引數之一的建構函式,那麼 Spring 就會查詢定義名為 SpellChecker 的 bean,並用它來設定建構函式的引數。你仍然可以使用
package autowire;
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();
}
}
SpellChecker.java
package autowire;
public class SpellChecker {
public SpellChecker() {
System.out.println("Inside SpellChecker constructor.");
}
public void checkSpelling() {
System.out.println("Inside checkSpelling." );
}
}
MainApp.java
package autowire;
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");
TextEditor te = (TextEditor)context.getBean("textEditor");
te.spellCheck();
}
}
下面是在正常情況下的配置檔案 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">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="autowire.TextEditor">
<constructor-arg ref="spellChecker" />
<constructor-arg value="Generic Text Editor"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id="spellChecker" class="autowire.SpellChecker">
</bean>
</beans>
但是,如果你要使用自動裝配 “by constructor”,那麼你的 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">
<!-- Definition for textEditor bean -->
<bean id="textEditor" class="autowire.TextEditor"
autowire="constructor">
<constructor-arg value="Generic Text Editor"/>
</bean>
<!-- Definition for spellChecker bean -->
<bean id="SpellChecker" class="autowire.SpellChecker">
</bean>
</beans>
Spirng基於註解的配置
從 Spring 2.5 開始就可以使用註解來配置依賴注入。而不是採用 XML 來描述一個 bean 連線,你可以使用相關類,方法或欄位宣告的註解,將 bean 配置移動到元件類本身。
在 XML 注入之前進行註解注入,因此後者的配置將通過兩種方式的屬性連線被前者重寫。
註解連線在預設情況下在 Spring 容器中不開啟。因此,在可以使用基於註解的連線之前,我們將需要在我們的 Spring 配置檔案中啟用它。所以如果你想在 Spring 應用程式中使用的任何註解,可以考慮到下面的配置檔案。
<?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/>
<!-- bean definitions go here -->
</beans>
一旦 被配置後,你就可以開始註解你的程式碼,表明 Spring 應該自動連線值到屬性,方法和建構函式。讓我們來看看幾個重要的註解,並且瞭解它們是如何工作的:
序號 | 註解 & 描述 |
---|---|
1 | @Required@Required 註解應用於 bean 屬性的 setter 方法。 |
2 | @Autowired@Autowired 註解可以應用到 bean 屬性的 setter 方法,非 setter 方法,建構函式和屬性。 |
3 | @Qualifier通過指定確切的將被連線的 bean,@Autowired 和 @Qualifier 註解可以用來刪除混亂。 |
4 | JSR-250 AnnotationsSpring 支援 JSR-250 的基礎的註解,其中包括了 @Resource,@PostConstruct 和 @PreDestroy 註解。 |
Spring @Required註釋:
@Required 註釋應用於 bean 屬性的 setter 方法,它表明受影響的 bean 屬性在配置時必須放在 XML 配置檔案中,否則容器就會丟擲一個 BeanInitializationException 異常。下面顯示的是一個使用 @Required 註釋的示例。
示例:
Student.java
package annotation;
import org.springframework.beans.factory.annotation.Required;
public class Student {
private Integer age;
private String name;
public Integer getAge() {
return age;
}
@Required
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
@Required
public void setName(String name) {
this.name = name;
}
}
MainApp.java
package annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("Student.xml");
Student student = (Student) context.getBean("student");
System.out.println("Name : " + student.getName() );
System.out.println("Age : " + student.getAge() );
}
}
Student.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"
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="annotation.Student">
<property name="name" value="Zara" />
<property name="age" value="11" />
</bean>
</beans>
Spring @Autowired註釋:
@Autowired 註釋對在哪裡和如何完成自動連線提供了更多的細微的控制。
@Autowired 註釋可以在 setter 方法中被用於自動連線 bean,就像 @Autowired 註釋,容器,一個屬性或者任意命名的可能帶有多個引數的方法。
Setter方法中的@autowired:
可以在 XML 檔案中的 setter 方法中使用 @Autowired 註釋來除去 元素。當 Spring遇到一個在 setter 方法中使用的 @Autowired 註釋,它會在方法中檢視執行 byType 自動連線。
屬性中的@autowired:
可以在屬性中使用 @Autowired 註釋來除去 setter 方法。當時使用 為自動連線屬性傳遞的時候,Spring 會將這些傳遞過來的值或者引用自動分配給那些屬性。
建構函式中的@Autowired:
可以在建構函式中使用 @Autowired。一個建構函式@Autowired 說明當建立 bean 時,即使在 XML 檔案中沒有使用元素配置 bean ,建構函式也會被自動連線。
@Autowired的(required=false)選項:
預設情況下,@Autowired 註釋意味著依賴是必須的,它類似於 @Required 註釋,然而,你可以使用 @Autowired的 (required=false) 選項關閉預設行為。
@Autowired(required=false)
Spring @Qualifier註釋:
可能會有這樣一種情況,當你建立多個具有相同型別的 bean 時,並且想要用一個屬性只為它們其中的一個進行裝配,在這種情況下,你可以使用 @Qualifier 註釋和 @Autowired 註釋通過指定哪一個真正的 bean 將會被裝配來消除混亂。
示例:
Student.java
package annotation;
public class Student {
private Integer age;
private String name;
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Profile.java
package annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Profile {
@Autowired
//在屬性中使用 **@Autowired** 註釋來除去 setter 方法。
@Qualifier("student2")
//指定Bean
private Student student;
public Profile(){
System.out.println("Inside Profile constructor." );
}
public void printAge() {
System.out.println("Age : " + student.getAge() );
}
public void printName() {
System.out.println("Name : " + student.getName() );
}
}
MainApp.java
package annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("Student.xml");
Profile profile = (Profile)context.getBean("profile");
profile.printName();
profile.printAge();
}
}
Student.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"
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/>
<bean id="profile" class="annotation.Profile" >
</bean>
<!-- Definition for student bean -->
<bean id="student1" class="annotation.Student">
<property name="name" value="Zara" />
<property name="age" value="11"/>
</bean>
<bean id="student2" class="annotation.Student">
<property name="name" value="join" />
<property name="age" value="13"/>
</bean>
</beans>
Spring JSR-250註釋:
Spring還使用基於 JSR-250 註釋,它包括 @PostConstruct, @PreDestroy 和 @Resource 註釋。
@PostConstruct 和 @PreDestroy 註釋:
為了定義一個 bean 的安裝和解除安裝,我們使用 init-method 和/或 destroy-method 引數簡單的宣告一下 。init-method 屬性指定了一個方法,該方法在 bean 的例項化階段會立即被呼叫。同樣地,destroy-method 指定了一個方法,該方法只在一個 bean 從容器中刪除之前被呼叫。
你可以使用 @PostConstruct 註釋作為初始化回撥函式的一個替代,@PreDestroy 註釋作為銷燬回撥函式的一個替代。
@Resource 註釋:
可以在欄位中或者 setter 方法中使用 @Resource 註釋,它和在 Java EE 5 中的運作是一樣的。@Resource 註釋使用一個 ‘name’ 屬性,該屬性以一個 bean 名稱的形式被注入。你可以說,它遵循 by-name 自動連線語義。
Spring基於Java的配置:
基於 Java 的配置選項,可以使在不用配置 XML 的情況下編寫大多數的 Spring,但是一些有幫助的基於 Java 的註解,解釋如下:
@Configuration 和 @Bean 註解
帶有 @Configuration 的註解類表示這個類可以使用 Spring IoC 容器作為 bean 定義的來源。@Bean 註解告訴 Spring,一個帶有 @Bean 的註解方法將返回一個物件,該物件應該被註冊為在 Spring 應用程式上下文中的 bean。
示例:
HelloWorldConfig.java
package annotation;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HelloWorldConfig {
@Bean
public HelloWorld helloWorld() {
return new HelloWorld();
}
}
HelloWorld.java
package annotation;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
MainApp.java
package annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp3 {
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(HelloWorldConfig.class);
HelloWorld helloWorld = ctx.getBean(HelloWorld.class);
helloWorld.setMessage("Hello World!");
helloWorld.getMessage();
}
}
注入Bean的依賴性:
當 @Beans 依賴對方時,表達這種依賴性非常簡單,只要有一個 bean 方法呼叫另一個。如下所示:
package com.tutorialspoint;
import org.springframework.context.annotation.*;
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}
這裡,foo Bean 通過建構函式注入來接收參考基準。
@Import註釋:
@import 註解允許從另一個配置類中載入 @Bean 定義。考慮 ConfigA 類,如下所示:
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
你可以在另一個 Bean 宣告中匯入上述 Bean 宣告,如下所示:
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B a() {
return new A();
}
}
現在,當例項化上下文時,不需要同時指定 ConfigA.class 和 ConfigB.class,只有 ConfigB 類需要提供,如下所示:
public static void main(String[] args) {
ApplicationContext ctx =
new AnnotationConfigApplicationContext(ConfigB.class);
// now both beans A and B will be available...
A a = ctx.getBean(A.class);
B b = ctx.getBean(B.class);
}
生命週期回撥:
@Bean 註解支援指定任意的初始化和銷燬的回撥方法,就像在 bean 元素中 Spring 的 XML 的初始化方法和銷燬方法的屬性:
public class Foo {
public void init() {
// initialization logic
}
public void cleanup() {
// destruction logic
}
}
@Configuration
public class AppConfig {
@Bean(initMethod = "init", destroyMethod = "cleanup" )
public Foo foo() {
return new Foo();
}
}
指定 Bean 的範圍:
預設範圍是單例項,但是你可以重寫帶有 @Scope 註解的該方法,如下所示:
@Configuration
public class AppConfig {
@Bean
@Scope("prototype")
public Foo foo() {
return new Foo();
}
}
Spring中的事件處理:
Spring 的核心是 ApplicationContext,它負責管理 beans 的完整生命週期。當載入 beans 時,ApplicationContext 釋出某些型別的事件。例如,當上下文啟動時,ContextStartedEvent 釋出,當上下文停止時,ContextStoppedEvent 釋出。
通過 ApplicationEvent 類和 ApplicationListener 介面來提供在 ApplicationContext 中處理事件。如果一個 bean 實現 ApplicationListener,那麼每次 ApplicationEvent 被髮布到 ApplicationContext 上,那個 bean 會被通知。
Spring 提供了以下的標準事件:
序號 | Spring 內建事件 & 描述 |
---|---|
1 | ContextRefreshedEvent ApplicationContext 被初始化或重新整理時,該事件被髮布。這也可以在 ConfigurableApplicationContext 介面中使用 refresh() 方法來發生。 |
2 | ContextStartedEvent 當使用 ConfigurableApplicationContext 介面中的 start() 方法啟動 ApplicationContext 時,該事件被髮布。你可以調查你的資料庫,或者你可以在接受到這個事件後重啟任何停止的應用程式。 |
3 | ContextStoppedEvent 當使用 ConfigurableApplicationContext 介面中的 stop() 方法停止 ApplicationContext 時,釋出這個事件。你可以在接受到這個事件後做必要的清理的工作。 |
4 | ContextClosedEvent 當使用 ConfigurableApplicationContext 介面中的 close() 方法關閉 ApplicationContext 時,該事件被髮布。一個已關閉的上下文到達生命週期末端;它不能被重新整理或重啟。 |
5 | RequestHandledEvent 這是一個 web-specific 事件,告訴所有 bean HTTP 請求已經被服務。 |
由於 Spring 的事件處理是單執行緒的,所以如果一個事件被髮布,直至並且除非所有的接收者得到的該訊息,該程序被阻塞並且流程將不會繼續。因此,如果事件處理被使用,在設計應用程式時應注意。
監聽上下文事件:
為了監聽上下文事件,一個 bean 應該實現只有一個方法 onApplicationEvent() 的 ApplicationListener 介面。因此,我們寫一個例子來看看事件是如何傳播的,以及如何可以用程式碼來執行基於某些事件所需的任務。
HelloWorld.java
package annotation;
public class HelloWorld {
private String message;
public void setMessage(String message){
this.message = message;
}
public void getMessage(){
System.out.println("Your Message : " + message);
}
}
CStartEventHandler.java
package annotation;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStartedEvent;
public class CStartEventHandler
implements ApplicationListener<ContextStartedEvent> {
@Override
public void onApplicationEvent(ContextStartedEvent arg0) {
System.out.println("ContextStartedEvent Received");
}
}
CStopEventHandler.java
package annotation;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler implements
ApplicationListener<ContextStoppedEvent> {
@Override
public void onApplicationEvent(ContextStoppedEvent arg0) {
System.out.println("ContextStoppedEvent Received");
}
}
MainApp4.java
package annotation;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp4 {
public static void main(String[] args) {
ConfigurableApplicationContext context = new
ClassPathXmlApplicationContext("Event.xml");
context.start();
HelloWorld obj = (HelloWorld)context.getBean("helloWorld");
obj.getMessage();
context.stop();
}
}
Event.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="helloWorld" class="annotation.HelloWorld">
<property name="message" value="Hello World!"/>
</bean>
<bean id="cStartEventHandler"
class="annotation.CStartEventHandler"/>
<bean id="cStopEventHandler"
class="annotation.CStopEventHandler"/>
</beans>
執行結果:
ContextStartedEvent Received
Your Message : Hello World!
ContextStoppedEvent Received
Spring中的自定義事件:
這個是 CustomEvent.java 檔案的內容:
package annotation;
import org.springframework.context.ApplicationEvent;
public class CustomEvent extends ApplicationEvent{
public CustomEvent(Object source) {
super(source);
}
public String toString() {
return "My Custom Event";
}
}
下面是 CustomEventPublisher.java 檔案的內容:
package annotation;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher
implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
public void setApplicationEventPublisher
(ApplicationEventPublisher publisher){
this.publisher = publisher;
}
public void publish() {
CustomEvent ce = new CustomEvent(this);
publisher.publishEvent(ce);
}
}
package com.tutorialspoint;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationEventPublisherAware;
public class CustomEventPublisher
implements ApplicationEventPublisherAware {
private ApplicationEventPublisher publisher;
public void setApplicationEventPublisher
(ApplicationEventPublisher publisher){
this.publisher = publisher;
}
public void publish() {
CustomEvent ce = new CustomEvent(this);
publisher.publishEvent(ce);
}
}
下面是 CustomEventHandler.java 檔案的內容:
package annotation;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextStoppedEvent;
public class CStopEventHandler implements
ApplicationListener<ContextStoppedEvent> {
@Override
public void onApplicationEvent(ContextStoppedEvent arg0) {
System.out.println("ContextStoppedEvent Received");
}
}
下面是 MainApp.java 檔案的內容:
package annotation;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp5 {
public static void main(String[] args) {
ConfigurableApplicationContext context = new
ClassPathXmlApplicationContext("Custom.xml");
CustomEventPublisher cvp = (CustomEventPublisher)
context.getBean("customEventPublisher");
cvp.publish();
cvp.publish();
}
}
下面是配置檔案Custom.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="customEventHandler"
class="annotation.CustomEventHandler"/>
<bean id="customEventPublisher"
class="annotation.CustomEventPublisher"/>
</beans>
程式執行結果:
My Custom Event
My Custom Event
不同配置方式的比較
基於XML配置 | 基於註解配置 | 基於Java類配置 |
---|---|---|
Bean定義 | 在XML檔案中通過 |