與xml哪個好, 各有利弊
注釋更簡潔, XML不需要編譯,更擅長鏈接組件。
有人認為: 注釋類不是簡單的POJO, 配置分散難控制。
Spring兼容兩種,可以混合使用,而且支持無侵入的注釋。
Spring 2.0 開始支持 @Required
Spring 2.5 @Autowired @PostConstruct, and?@PreDestroy
Spring 3.0 @Inject?and?@Named
更多可參考?relevant section.
需要加上
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
</beans>
重點:
?<context:annotation-config/>?在?WebApplicationContext for DispatcherServlet, 只會在controllers中檢查@Autowired, 不會在services中檢查。
1.9.1 @Required
這個注釋應用在屬性的setter方法上。
必須執行檢查。
1.9.1 @Autowired
可以加在構造方法上。
在 Spring 4.3版本, 如果只有一個構造器則不需要加上這個注釋;但是如果有多個構造器,則必須指定使用哪一個。
@Autowired也可以使用在其他帶有多個參數的方法上。也可以在屬性上和構造函數上同時使用
public class MovieRecommender {
private final CustomerPreferenceDao customerPreferenceDao;
@Autowired
private MovieCatalog movieCatalog;
@Autowired
public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
}
也可以使用在數組上
public class MovieRecommender {
@Autowired
private MovieCatalog[] movieCatalogs;
// ...
}
}
等效于以下:
public class MovieRecommender {
private Set<MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Set<MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
}
目標bean這里是 MovieCatalog, 可以繼承org.springframework.core.Ordered接口, 使用 @Order 或者@Priority注釋設定順序。否則會根據注冊的順序。
標準的javax.annotation.Priority?注釋自從無法在方法上聲明后在@Bean層級就無法使用了, 可以通過@Order 結合@Primary?達成。
Map類型的也可以autowired,
public class MovieRecommender {
private Map<String, MovieCatalog> movieCatalogs;
@Autowired
public void setMovieCatalogs(Map<String, MovieCatalog> movieCatalogs) {
this.movieCatalogs = movieCatalogs;
}
// ...
}
}
如果找不到合適的bean的話, autowire會失敗, 可以通過設置required = false
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Autowired(required = false)
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
// ...
}
}
重要:一個類只能有一個構造函數可以標識為required, 但是可以有多個構造函數可以表示為 non-required. 在這種狀況下, spring使用參數最多的構造函數。
java8 可以使用java.util.Optional來處理非必須的特性。
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
...
}
}
}
在Spring 5中, 可以使用@Nullable 注釋
public class SimpleMovieLister {
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
...
}
}
}
eanFactory,?ApplicationContext,?Environment,?ResourceLoader,?ApplicationEventPublisher, and?MessageSource這些也可以使用@Autowired。
public class MovieRecommender {
@Autowired
private ApplicationContext context;
public MovieRecommender() {
}
// ...
}
}
1.9.3 使用@Primary 可以很好調優基于注解的自動裝配
@Configuration
public class MovieConfiguration {
@Bean
@Primary
public MovieCatalog firstMovieCatalog() { ... }
@Bean
public MovieCatalog secondMovieCatalog() { ... }
// ...
}
}
使用這個配置之后, 以下會自動裝配firstMovieCatalog
public class MovieRecommender {
@Autowired
private MovieCatalog movieCatalog;
// ...
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<bean class="example.SimpleMovieCatalog" primary="true">
<!-- inject any dependencies required by this bean -->
</bean>
<bean class="example.SimpleMovieCatalog">
<!-- inject any dependencies required by this bean -->
</bean>
<bean id="movieRecommender" class="example.MovieRecommender"/>
</beans>
1.9.4 使用@Qualifier?調優
@Primary可以指定先用哪一個,更多的控制可以使用@Qualifier?
public class MovieRecommender {
@Autowired
@Qualifier("main")
private MovieCatalog movieCatalog;
// ...
}
}
@Qualifier也可以使用在構造函數的參數上
public class MovieRecommender {
private MovieCatalog movieCatalog;
private CustomerPreferenceDao customerPreferenceDao;
@Autowired
public void prepare(@Qualifier("main")MovieCatalog movieCatalog,
CustomerPreferenceDao customerPreferenceDao) {
this.movieCatalog = movieCatalog;
this.customerPreferenceDao = customerPreferenceDao;
}
// ...
}
}
@Qualifier也可以定制
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {
String value();
}
}
1.9.7 @Resource
@Resource - JSR-250
@Resource有name的屬性, spring 會將其作為bean的名字
public class SimpleMovieLister {
private MovieFinder movieFinder;
@Resource(name="myMovieFinder")
public void setMovieFinder(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}
}
}
如果沒有指定 name, 則會使用setter 的name。
1.9.8. @PostConstruct and @PreDestroy
- 空白目錄
- 0.環境準備
- 0.1基于maven的工程創建
- 1.控制反轉容器
- 1.1 Spring控制反轉容器和beans介紹
- 1.2 容器概覽
- 1.3 Bean概覽
- 1.4 依賴
- 1.5 Bean的范圍
- 1.6 客制bean的特性
- 1.7 Bean定義的繼承
- 1.8 容器擴展點
- 1.9 基于注解的容器配置
- 1.10 類路徑掃描及組件管理
- 1.11 使用JSR 330標準的注解
- 1.12 基于Java的容器配置
- 1.12.1 基本概念: @Bean 和 @Configuration
- 1.13 環境抽象化
- 1.14 注冊一個LoadTimeWeaver
- 1.15 ApplicationContext的附加功能
- 1.16 BeanFactory
- 2. 資源
- 3. 驗證,數據綁定和類型轉換
- 4. Spring表達式語言(SpEL)
- 5. Spring面向方面的切面編程
- 6. Spring AOP 接口
- 7. 空安全
- 8. 數據緩沖和編碼
- 9. 附錄