Spring配置的可選方案
1. 隱式的bean發現機制和自動配置
2. 在Java中進行顯式配置
3. 在XML中進行顯式配置
自動化裝配bean
spring從兩個角度來實現自動化裝配
- 組件掃描(component scanning):Spring會自動發現應用上下文中所創建的bean
- 自動裝配(autowiring):Spring自動滿足bean之間的依賴
public interface UserService{
void goHome();
}
@Component
public class UserServiceImpl implements UserService{
public void goHome(){
System.out.println("");
}
}
@Component 註解表明該類作爲組件類,並告知Spring要爲這個類創建bean。沒有必要顯式配置 UserServiceImpl bean,因爲這個類使用了@Component 註解,所以spring會爲你把事情處理妥當。
不過,組件掃描默認是不開啓的。我們還需要顯式配置一下Spring,從而命令它去尋找帶有@Component註解的類,併爲其創建bean。
import org.springframework.context.annotation.componentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan
public class UserConfig{
}
@ComponentScan 默認會掃描與配置類相同的包,通過掃描這個包以及這個包下面的所有的子包,查找帶有@Component註解的類,並執行操作。
如果更傾向於XML來啓用組件掃描的話,那麼可以使用Spring context 命名空間的 < context:component-scan > 元素
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:p="http://www.springframework.org/schema/p"
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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="" />
</beans>
爲組建掃描的bean命名
Spring應用上下文所有的bean都會給定一個ID,上面的例子雖然沒有指定,但spring會根據類名指定(將首字母變爲小寫),如果我們想的爲一個bean設置不同的ID,那麼我們可以將代碼改爲
@Component("driver")
public class UserServiceImpl implements UserService{
'''
}
好吧,其實我們也可以不用@Component註解,而是用Java依賴注入規範中提供的@Named註解爲bean設置ID
import javax.inject.Named;
@Named("driver")
public class UserServiceImpl implements UserService{
'''
}
設置組件掃描的基礎包
目前爲止我們對@ComponentScan 設置任何屬性,這意味着,按照默認規則,會以配置類所在的包作爲基礎類(base package)來掃描組件。
@Configuration
@ComponentScan("basePackage")
public class UserConfig{
}
小擴展
@ComponentScan() 可以設置value或basePackages屬性嗎,兩個都是數組
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
//安全的注入需要bean的Class
Class<?>[] basePackageClasses() default {};
通過爲bean添加註解實現自動裝配
自動裝配就是讓Spring自動滿足bean依賴的一種方法,在滿足依賴的過程中,會在應用上下文中尋找匹配某個需求的其他bean,我們可以利用Spring的@Autowired註解完成。
@Component
public class EduFactory{
private UserService userService;
@Autowired
public EduFactory (UserService userService){
this.userService = userService;
}
'''
}
在Spring初始化bean之後它會盡可能滿足bean依賴,@Autowired可以用在類方法上,假設我們沒把該註解在Setter方法上,而放在insertUs方法上,那麼該註解發揮的作用還是完全一樣的。
@Autowired
public void insertUs(UserService userService){
this.userService = userService;
}
不管是構造器還是Setter方法,Spring都會嘗試滿足方法參數上所聲明的依賴, 如果有就封裝起來,未發現則會跑出異常,通過**@Autowired(required = false)**註解可以防止報錯,但是在代碼中要對其判斷處理,以防止出現NullPointerExcepton異常。 (預留匹配多個的小坑)
@Autowired是Spring特有註解,我們還可以使用@Inject方法來進行裝配
import javax.inject.Inject;
import javax.inject.Named;
@Named("driver")
public class EduFactory UserService{
@Inject
public UserServiceImpl (UserService userService){
this.userService = userService;
}
'''
}