Spring基于Java配置的容器
????一、Bean 管理????????1. 元數據????????2. Full 模式和 Lite 模式????????3. 組合配置????????4. 掃描類路徑配置????二、依賴管理????????1. 依賴注入????????????1.1 參數注入????????????1.2 方法注入????????2. 依賴關系????????3. 懶加載????三、附錄????????1. 常用注解????????2. 示例代碼
Spring 容器的元數據可以基于 Java 代碼配置,它像 XML 配置一樣不侵入源代碼,同時也支持注解配置。
你可以在項目中任意選擇哪種配置方式,或者多種方式共存。
一、Bean 管理
1. 元數據
基于 Java 配置 Bean,定義一個類并使用@Configuration注解作為配置類,在類中的方法上使用@Bean注解,就會注冊一個以方法返回值為實例的 Bean。
@Configuration
public?class?AppConfig?{
????@Bean
????public?BeanExample beanExample()?{
????????return?new?BeanExample();
????}
????@Bean
????public?BeanProvider beanProvider()?{
????????return?new?BeanProvider();
????}
}默認使用方法名稱作為 Bean 名稱,也可以通過注解的value或name屬性來指定。
使用AnnotationConfigApplicationContext來實例化容器。
public?static?void?main(String[] args)?{
????ApplicationContext applicationContext =
????????new?AnnotationConfigApplicationContext(AppConfig.class);
????BeanExample beanExample = (BeanExample) applicationContext.getBean("beanExample");
}Bean 作用域
使用@Scope注解來指定 Bean 的作用域。
@Bean
@Scope("singleton")
public?BeanExample beanExample()?{
????return?new?BeanExample();
}作用域類型參閱《Spring基于XML配置的容器》
2. Full 模式和 Lite 模式
一般情況下,@Bean用于@Configuration注解的類下,這種方式為 Full 模式。
當@Bean用于其他注解(如@Component)的類下,或者為任何一個 Bean 內部的方法,這種情況為 Lite 模式。
// Full
@Configuration
public?class?AppConfig?{
????@Bean
????public?BeanExample beanExample()?{
????????return?new?BeanExample();
????}
}
// Lite
@Component
public?class?AppConfig?{
????@Bean
????public?BeanExample beanExample()?{
????????return?new?BeanExample();
????}
}Full 模式會生成 CGLIB 代理類,可以通過方法調用來依賴其它 Bean。
Lite 模式則不生成,可以提高運行性能,降低啟動時間。
為了避免方法調用注入依賴的 Bug,推薦在業(yè)務中使用 Full 模式,在組件工具封裝中使用 Lite 模式。
Spring 5.2.x 版本后,
@Configuration可以指定屬性proxyBeanMethods為 false,來禁用 CGLIB 進入 Lite 模式。
3. 組合配置
為了實現(xiàn)模塊化配置,可以定義多個配置類,在配置類中使用@Import注解來導入其他配置類。
在實例化容器的時候,只需要指定AppConfig類,不需要指定所有配置類。
@Configuration
public?class?OtherConfig?{
????@Bean
????public?BeanProvider beanProvider()?{
????????return?new?BeanProvider();
????}
}
@Configuration
@Import(OtherConfig.class)
public?class?AppConfig?{
????@Bean
????public?BeanExample beanExample(BeanProvider beanProvider)?{
????????BeanExample beanExample = new?BeanExample();
????????beanExample.setBeanProvider(beanProvider);
????????return?beanExample;
????}
}4. 掃描類路徑配置
使用@ComponentScan來配置掃描的包路徑,支持基于注解配置。
@Configuration
@ComponentScan(basePackages = "cn.codeartist.spring.bean.java")
public?class?AppConfig?{
}參閱上一篇《Spring基于注解配置的容器》
二、依賴管理
配置類同樣是一個 Bean,也支持字段注入、構造器注入和 Setter 方法注入依賴。
@Configuration
public?class?AppConfig?{
????@Autowired
????private?BeanProvider beanProvider;
????@Bean
????public?BeanExample beanExample()?{
????????BeanExample beanExample = new?BeanExample();
????????beanExample.setBeanProvider(beanProvider);
????????return?beanExample;
????}
}1. 依賴注入
1.1 參數注入
依賴的 Bean 可以通過方法參數注入。
@Bean
public?BeanExample beanExample(BeanProvider beanProvider)?{
????BeanExample beanExample = new?BeanExample();
????beanExample.setBeanProvider(beanProvider);
????return?beanExample;
}1.2 方法注入
在同一個配置類中,可以直接調用方法來依賴其它 Bean,該方式只在生成 CBLIB 代理類的 Full 模式下才生效。
@Configuration
public?class?AppConfig?{
????@Bean
????public?BeanExample beanExample()?{
????????BeanExample beanExample = new?BeanExample();
????????beanExample.setBeanProvider(beanProvider());
????????return?beanExample;
????}
????@Bean
????public?BeanProvider beanProvider()?{
????????return?new?BeanProvider();
????}
}2. 依賴關系
使用@DependsOn注解指定依賴關系。
@Bean
@DependsOn("beanProvider")
public?BeanExample beanExample()?{
????return?new?BeanExample();
}3. 懶加載
使用@Lazy注解配置懶加載。
@Lazy
@Bean
public?BeanProvider beanProvider()?{
????return?new?BeanProvider();
}懶加載 Bean 在注入的地方也要加上@Lazy注解,或者使用ApplicationContext.getBean()方法獲取 Bean,才能使懶加載生效。
@Bean
public?BeanExample beanExample(@Lazy BeanProvider beanProvider)?{
????BeanExample beanExample = new?BeanExample();
????beanExample.setBeanProvider(beanProvider);
????return?beanExample;
}三、附錄
1. 常用注解
| 注解 | 描述 |
|---|---|
@Configuration | 指定 Bean 的配置類 |
@Bean | 配置 Bean 元數據,作用于方法上,方法返回值作為 Bean 實例 |
@Scope | 指定 Bean 的作用域 |
@Import | 導入其他配置類 |
@DependsOn | 指定 Bean 的依賴關系 |
@Lazy | 配置懶加載 |
2. 示例代碼
Gitee 倉庫:
https://gitee.com/code_artist/spring
項目模塊:
spring-ioc
示例路徑:
cn.codeartist.spring.bean.java
