三種主要裝配方式:
- 自動化配置
- 基于Java的顯示配置
- 基于XML的顯示配置
對比了三種配置,覺得工作中應盡可能使用自動化配置,避免顯示配置所帶來的維護成本。 如果確實需要顯示配置,優(yōu)先Java配置,比XML配置更強大,類型更安全且易于重構。
profile的激活
Spring在確定哪個profile處于激活狀態(tài)時,需要依賴兩個獨立屬性:
spring.profiles.active和spring.profiles.default。
有多重方法設置這兩種屬性:
- DispatcherServlet的參數
- Web應用的上下文參數
- JNDI條目
- 環(huán)境變量
- JVM系統(tǒng)屬性
- 集成測試類中用@ActiveProfile設置
從Spring 4 開始,@Profile注解進行了重構,使其基于@Conditional和Condition實現(xiàn)。實現(xiàn)見“Spring bean 相關Annotation收集整理”
處理自動裝配的歧義性
如果不僅有一個bean能夠匹配結果,歧義性會阻礙Spring自動裝配屬性、構造器參數或方法參數。比如用@Autowired標注了某個X的set方法,而X是一個有3個實現(xiàn)類的接口,且這三個類均使用了@Component注解。此時Spring會拋出NoUniqueBeanDefinitionException。
解決辦法:
1)標示首選的Bean,通過@Primary。(同一接口下只能有一個Primary bean)
2)使用限定符
-
@Qualifier("classname"),classname可以為自定義的限定符,而不是依賴于將beanID作為限定符。 - 使用自定義的限定符注解:
@Target({ElementType.CONSTRUCTOR, ElementType.FIELD,
ElmentType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface YourAnnotation{ }
然后,
@Autowired
@Qualifier("自定義限定符名")
@YourAnnotation
public void setAA(AA aa){
this.aa = aa;
}
Bean的作用域
Spring定義了多種作用域,可以基于這些作用域創(chuàng)建bean,包括:
- 單例(Singleton):在整個應用中,只創(chuàng)建bean的一個實例。
- 原型(Prototype):每次注入或通過Spring應用上下文獲取時,都會創(chuàng)建一個新的bean實例。
- 會話(Session):在Web應用中,為每個會話創(chuàng)建一個bean實例。
- 請求(Rquest):在Web應用中,為每個請求創(chuàng)建一個bean實例。
單例為默認作用域,但對于易變的類型不合適。如果選擇其他的作用域,要使用@Scope注解,可以與@Component或@Bean一起使用。
在運行時值注入
有時,我們可能會希望避免硬編碼值,并讓這些值在運行時再確定。Spring有兩種在運行時求值的方式:
- 屬性占位符(Property placeholder)
- Spring表達式語言(SpEL)
注入外部的值
使用外部屬性來裝配一個bean:
@Configuration
@PropertySource("classpath:/路徑/app.properties") //聲明屬性源
public class ExpressiveConfig{
@Autowired
Environment env;
@Bean
public XX x(){
return new XX(
env.getProperty("x.title"),
env.getProperty("x.artist"));
}
}
在本例中,@PropertySource引用了類路徑中名為app.properties的文件。大致如下所示:
x.title = xxxxx
x.artist = xxxax
這個屬性的文件會加載到Spring的Environment中,稍后可以從這里檢索屬性。同時,在x()中,會創(chuàng)建一個新的XX,他的構造器參數是從屬性文件中獲取的,而這時通過調用getProperty()實現(xiàn)的。
解析屬性占位符
Spring支持將屬性定義到外部的屬性文件,并使用占位符值將其插入到Spring bean中。在Spring裝配中,占位符的形式為使用${...}包裝屬性名稱。
使用SpEL進行裝配
SpEL(Spring Expression Languae)是Spring3引入的一種強大簡潔的將值裝配到bean屬性和構造器參數中的方式。
SpELl特性:
- 使用bean的id引用bean;
- 調用方法和訪問對象的屬性;
- 對值進行算術、關系和邏輯運算;
- 正則表達式匹配;
- 集合操作。
SpEL需要放入“#{...}”之中。
SpEL表達式可以引用其他的bean或其他bean的屬性:
#{id.attributename}
與@Value結合:
public ClassName{
@Value("#{systemProperties['id.attributename']}") String attributename,
@Value("#{systemProperties['id.anotherattributename']}") String anotherattributename){
this.attributename= attributename;
this.anotherattributename= anotherattributename;
}
還有很多其他功能,有機會整理一篇具體功能再發(fā)。