Spring3聲明完全支援JSR-330規格:@Inject、@Qualifier、@Named、@Provider、@Scope和@Singleton,最早Google Guice 2也支援,兩者有異曲同工之妙。在Spring3把@Autowired完全可以用@Inject(javax.inject)取代,因為@Autowired在JSR-330之前就有了,而現在有一個需求是,吾人定義一個共用的Interface:IBaseDao<T>,放著insert、update、delete等共同操作,但T可能是不同物件,如Account、Employee等,在Spring 2.5.x以前的版本,是在context xml裡配置好不同bean name,但在Spring3的annotion context如何做到?答案是@Qualifier。

在Config類別設定如下:

@Bean(name="AccountDao")        // 相當於為bean指定name
public IBaseDao AccountDao() {  // 回傳型態為IBaseDao<Accounts>更精準 ^_^
    return new AccountDaoImpl();
}

在JUnit去測試它:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, 
        value = "com.foo.dao.DaoConfig")
public class TestAccountDao {
    private static Logger logger = LoggerFactory.getLogger(TestAccountDao.class);
    @Autowired
    @Qualifier
("accountDao")    // 指定bean name
    private IBaseDao<Accounts> baseDao;
    @Test
    public void testDao() {
        //… 略

    }
}

  而Spring3的@Qualifier也可自訂annotation,和Guice的@Named用法頗為雷同,可參考Guice用annotation配置DI。以下列表作比較

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
    String value();
}
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.CONSTRUCTOR})
@Retention ( RetentionPolicy.RUNTIME )
@BindingAnnotation
public @interface Genre {
    String value();
}

  因為Spring 2.5.x早在JSR-330釋出前有部份雷同實作,到Spring3再回頭補足JSR-330規範的Annotation名稱,是故Survey上會有所confuse。

  1. Spring3的@Autowired與JSR-330的@Inject完全相同,Spring3習慣是用@Autowired,而Guice則是有自己的@Inject。
  2. @Qualifier和@Named意義幾乎相同,差異在於後者是String base的@Qualifier。而Spring3選擇了@Qualifier,Guice選擇了@Named作為"修飾"。包括自訂annotation策略也相同。@Qualifier搭配@Autowired似乎可以修飾不同的DataSource
  3. @Provider在Spring3官方文件是一筆帶過,而從Guice文件說明來看:@Provider是將class的new、destroy的權力從預定的container拿回開發者上決定。比如部份bean元件是給Spring Application Context管理,可以藉由@Provider改為Guice或其它Ioc Container管理。這方面尚未研究。
  4. 還有@Scope,就是決定bean是Singleton還是prototype還是其它,在Spring和Guice都有相應用法。而@Singleton則是Guice提一個專屬的@Scope,這是Spring所沒有,相應用法是:@Scope(BeanDefinition.SCOPE_SINGLETON)
arrow
arrow
    全站熱搜

    Jemmy 發表在 痞客邦 留言(0) 人氣()