13 3月 2007

Dependency checking mechanism

Dependency checking mechanism 在使用Spring的dependency injection功能時,有不少人會希望使用constructor injection,主要是因為這樣同時可以確保所有的dependency都一定會被設定到,但我個人比較偏好使用method injection,一方面這樣比較好使用mock object來做測試,一方面我也不喜歡看到一長串難以分別順序的constructor,而且如果要新增一個subclass,那同時也要extends一個至少一樣長的Constructor... Spring forum最近發起了一個新的投票 How do you ensure required dependencies are set?,看看大家最常用的Dependency檢核機制是什麼,目前看來還是以Annotation @Required, implements InitializingBean後以assert檢查及Constructor injection三者略多,當然也有不少票是投給完全不檢查的... 因為我習慣使用method injection,所以在允許的環境下(一定要用JDK5),我也喜歡用@Required來檢查,如果環境不允許,我就會變成完全不檢查... 以spring提供的例子來看@Required的用法 在要檢查Dependency的setter method加上@Required
public class SimpleMovieLister {
 // the SimpleMovieLister has a dependency on the MovieFinder
 private MovieFinder movieFinder;
 // a setter method so that the Spring container can 'inject' a MovieFinder
 @Required
 public void setMovieFinder(MovieFinder movieFinder) {
  this.movieFinder = movieFinder;
 }
}
然後還需要在xml中加入
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
做為執行檢查@Required之用 如果原本開發系統已經有類似的Annotation,或是不想之後一定要使用Spring,可以使用自定的Annotation
package org.elliot.jdk;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Mandatory {

}
在xml只要加入像下列config即可使用自訂的Annotation達成相同的效果
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor">
 <property name="requiredAnnotationType" value="org.elliot.jdk.Mandatory"/>
</bean>

沒有留言: