JavaConfig是Spring的一個子項目,它旨在通過java類的方式提供Bean的定義資訊,普通的POJO只要標註@Configuration註解,就可以成為Spring容器提供的Bean定義的資訊了,每個標註了@Bean的類方法就相當於提供了一個Bean的定義資訊。
package spring.ioc.autowired;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import spring.ioc.demo1.Car;//將一個POJO標註定義為Sping Bean的配置類@Configuration public class ConfigurationUse { //每一個標註了@Bean的類方法都相當於提供了一個Bean的定義資訊 //Bean的類型由方法傳回值類型決定 car1對應xml中id=car1的Bean @Bean public Car car1(){ return new Car(); } public String toString(){ return car1().toString(); }}
<bean id="car1" class="spring.ioc.demo1.Car" scope="prototype" p:brand="spring注入-紅旗001" p:color="spring注入-紫色" p:maxSpeed="520" />
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); ConfigurationUse configurationUse = ctx.getBean(ConfigurationUse.class); System.out.println("@Configuration:" + configurationUse);}
輸出:@Configuration:the car is:spring注入-紅旗001, color is:spring注入-紫色, maxspeed is:520
如果Bean在多個@Configuration配置類中定義,我們也可以引用不同配置類中定義的Bean:
package spring.ioc.autowired;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.annotation.Configuration;@Configuration(value="configurationTemp")public class ConfigurationTemp { @Autowired ConfigurationUse configurationUse; public String toString(){ return configurationUse.car1().toString(); }}
public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); ConfigurationTemp configurationTemp = ctx.getBean("configurationTemp",ConfigurationTemp.class); System.out.println("ConfigurationTemp:" + configurationTemp);}
輸出:ConfigurationTemp:the car is:spring注入-紅旗001, color is:spring注入-紫色, maxspeed is:520
由於@Configuration註解類本身已經標註了@Component註解,所以任何標註了@Configuration的類,本身也相當於標註了@Component.
return configurationUse.car1()不是簡單的執行了ConfigurationUse中的方法邏輯,而是從Spring容器中返回相應的Car執行個體.
@Scope("Prototype")保證了每次從容器中拿的Car Bean都是最新狀態的.
基於XML、基於註解、基於Java類這三種方式的比較和總結
|
基於XML配置 |
基於註解配置 |
基於Java類配置 |
Bean定義 |
在XML中通過<bean>元素定義Bean,如:<bean id="bean1" class="com.360buy.bean1" |
在Bean的實作類別處通過標註@Compoent註解或者衍生(@Respository、@Service、@Controller)定義Bean |
在標註了@Congiguration的Java類中,通過在類方法上標註@Bean定義一個Bean.方法必須提供Bean的執行個體化邏輯 |
Bean名稱 |
通過<bean>的id或者name屬性定義 |
通過註解的value屬性定義,如: @Component(value="userDao") |
通過@Bean的name屬性定義,如: @Bean(name="userDao"),預設名稱為方法名 |
Bean注入 |
通過<property>子項目或者通過p命名空間的動態屬性. |
通過在成員變數或者方法入參處標註@Autowired,預設按類型自動注入,還可以配合使用@Qualifier按名稱匹配注入 |
比較靈活,可以通過在方法處通過@Autowired使方法參數綁定Bean,還可以通過調用配置類的@Bean方法進行注入 |
Bean生命程序呼叫方法 |
通過<bean>的init-method和destroy-method屬性指定Bean實作類別的方法名,最多隻能指定一個初始化方法和銷毀方法 |
通過在目標方法上標註@PostConstruct和@PreDestroy註解指定初始化方或銷毀方法,可以定義任意多個 |
通過@Bean的initMethod或destroyMethod指定一個初始化或者銷毀方法 |
Bean的作用範圍 |
通過<bean>的scope屬性指定 |
通過在類定義處標註@Scope("Propotype") |
通過在Bean方法定義處標註@Scope("Propotype") |
Bean延遲初始化 |
通過<bean>的lazy-init屬性指定,預設為default,繼承於<beans>的default-lazy-init設定,該預設值為false |
通過在類定義處標註@Lazy指定,如 @Lazy(true) |
通過在Bean方法定義處標註@Lazy指定 |
適用情境 |
1.Bean實作類別來源於第三方類庫,如DataSource、JdbcTemplate等,因為無法在類中標註註解,通過XML配置較好 2.命名空間的配置,如aop、context等只能通過基於XML的配置 |
Bean的實作類別是當前項目開發的,客戶以直接在java類中只用基於註解的配置 |
基於java類配置的優勢在於可以通過代碼方式控制Bean初始化的整體邏輯,所以如果執行個體化Bean的邏輯比較複雜,則比較適合用基於java類配置的方式 |