基於Java的配置元數據

基於Java的配置元數據

有了基於XML的配置元數據和基於註解的配置元數據(還是依賴XML,需要配置容器掃描的包,以至於能夠找到註解),再來了解一種脫離XML的形式,Java-based

用配置類代替XML

配置類和普通的Java類一樣,區別在於配置類被一些註解標註。

舉例:

public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}


ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);

@Bean

可以看到,在配置類Appconfig中有一個被@Bean標註的方法,這個方法返回一個實際類型爲MyServiceImpl的對象。

這個配置等價於:

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

細節:關於bean的id以及bean的類型

通過對照發現,缺省@Bean的屬性時,默認使用被@Bean修飾的方法的名稱,作爲bean的id

基於XML配置時,class指定bean的實際類型(通過反射機制創建對象);在基於Java的配置中,方法中的new MyseviceImpl()就相當於指定了class屬性。

AnnotationConfigApplicationContext(Class<?>…)

請注意,由於使用了基於Java的配置,所以不能使用基於XML的構造器來構建容器,因此引入基於Java配置類的的構造器,通過這個方法加載配置類。

@Configuration

這個註解的作用是標註一個類是配置類,在包掃描的時候,讓容器“知道”這個類是一個配置元數據,從而加載到容器中。

注意上面的例子,並沒有在AppConfig這個配置類上加上@Configuration註解,因爲加載配置元數據的方式是直接傳入構造器,而不是通過包掃描。(關於怎樣配置包掃描路徑,下面在介紹)

兼容基於註解的配置元數據 @ComponentScan

在介紹基於註解的配置時,特別強調XML中要配置包掃描路徑。因爲當時使用基於註解的配置時,構建容器時,傳入的參數是XML文件,所以必須告訴容器到“哪些”包下去“找”註解。

現在,基於Java的配置,不再使用XML,因此,對於包掃描的標籤,也需要使用註解的方式替換:@ComponentScan(basePackages = "org.example")等價於<context:component-scan base-package="org.example"/>

改變bean的Scope:@Scope

在之前討論@Bean註解的時候,爲了避免對各種標籤的混淆,所以刻意的跳過了關於bean的Scope配置的問題。再來看上面的配置:

public class AppConfig {

    @Bean
    public MyService myService() {
        return new MyServiceImpl();
    }
}

注意,這裏沒有指定myService這個bean的Scope(默認爲Singleton),因爲兼容基於註解的配置,所以可以使用@Scope來指定bean的Scope

public class AppConfig {

    @Bean
	@Scope("prototype")
    public MyService myService() {
        return new MyServiceImpl();
    }
}

再談@ComponentScan和@Configuration

在掃描包時,如果發現有類被@Configuration標註,容器就會將它當作配置類加載。

如果直接將某個類傳遞給構建容器的構造器,這個類即使不被Configuration標註,它也是被當作配置類加載。

最後再強調一點,僅有被@Bean修飾的方法,纔會產生bean,否則,容器會把他當作普通方法,而不是去創建一個默認名字爲方法名的bean

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章