一、@value
javaBean
public class Bird {
//使用@Value進行賦值:1,基本字符 2,springEL表達式, 3,可以讀取 我們的配置文件
@Value("James")
private String name;
@Value("#{20-2}")
private Integer age;
@Value("${bird.color}")
private String color;
public Bird() {
super();
}
public Bird(String name, Integer age, String color) {
super();
this.name = name;
this.age = age;
this.color = color;
}
//getter、setter 方法.......
}
config
@Configuration
//加載 properties 文件
@PropertySource("classpath:/test.properties")
public class Cap8MainConfig {
@Bean
public Bird bird(){
return new Bird();
}
}
properties
bird.color=red
test
public class Cap8Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfig.class);
Bird bird = (Bird) app.getBean("bird");
System.out.println(bird);
System.out.println("IOC容器創建完成........");
ConfigurableEnvironment environment = app.getEnvironment();
System.out.println("environment===="+environment.getProperty("bird.color"));
app.close();
}
}
輸出
Bird [name=James, age=18, color=red]
IOC容器創建完成........
environment====red
注:@PropertySource(“classpath:/test.properties”) 會把properties 配置文件中的標量都掃進環境變量中,@Value("${bird.color}")去環境變量中取值
二、註解方式 聲明 bean 與注入 bean
1.聲明bean的註解
@Component 組件,沒有明確的角色
@Service 在業務邏輯層使用(service層)
@Repository 在數據訪問層使用(dao層)
@Controller 在展現層使用,控制器的聲明(C)
注:以上註解納入 springBean中,默認bean的Id是類名首字母小寫,可選參數 value 可指定自定義 bean Id,如下:
如果是①,那麼這個 service 的 bean Id 就是 TtetService
如果是②,那麼 service 的 bean Id就是myTestService
//@Service(value = "myTestService") //②
@Service //①
public class TestService{
}
2、注入bean的註解
@Autowired:由Spring提供
@Inject:由JSR-330提供
@Resource:由JSR-250提供
都可以註解在set方法和屬性上,推薦註解在屬性上(一目瞭然,少寫代碼)。
@Autowired
1.@Autowired 是 spring 註解
2.@Autowired註解是按照類型(byType)裝配依賴對象.
3.默認情況下它要求依賴對象必須存在,如果允許null值,可以設置它的required屬性爲false。
4.如果我們想使用按照名稱(byName)來裝配,可以結合@Qualifier註解一起使用。
5.可以設置屬性@Autowired(required = false),表示如果沒有接口的實現類,那麼就注入 null
接口:
public interface ITestService {
void judgeService();
}
service 實現類1 TestService
@Service
public class TestService implements ITestService{
private TestDao testDao;
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 實現類2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller1
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired(required = true)
private TestService testService;
public void testSwichService(){
testService.judgeService();
}
}
controller2
@Controller
public class TestController {
@Autowired(required = true)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
controller3
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired(required = false)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
test
public class Cap9Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);
TestController testController = app.getBean(TestController.class);
testController.testSwichService();
}
}
說明:
1.如果執行的是 controller1,因爲注入的 service 類型定是具體的實現類 TestService,所以@Autowired通過 byType 可以確定的 service 是TestService,所以輸出的是『this is service2』
2.如果執行的是 contoller2,因爲注入的是一個接口ITestService:
如果沒有TestService2,ITestService的實現類就只有TestService,所以會正常的輸出『this is service』
現在ITestService有兩個實現類 TestService、TestService2,所以@Autowired就會不知道該注入哪個實現類,最後會報錯:發現了兩個實現類
3.如果執行的是 controller3,同樣注入的是一個接口ITestService,因爲有註解@Qualifier(“testService2”),代表指定ITestService接口實現類的 bean Id,且必須是實現了接口ITestService的 service,因爲此時@Autowired(required = false),所以找不到的話iTestService會爲 Null,不會報錯
@Resource
1.jdk 自帶註解,由JSR-250提供
2.默認按照 name(實際是 beanId)進行裝配,如果name匹配不到才按 type進行匹配。需要注意的是,如果只按 name 匹配,如果 name 匹配不到,就不會按照類型就行匹配了,會報找不到。
3.必須有一個合適的實現類注入進來,不然會報錯
接口
public interface ITestService {
void judgeService();
}
service 實現類1 TestService
@Service
public class TestService implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 實現類2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller
@Controller
public class TestController {
//所掃描的 bean 必須爲ITestService的實現類
//查找 beanId 爲 『testService』的 bean
@Resource(name = "testService")
//查找類型爲『TestService.class』的 bean
@Resource(type = TestService.class)
//查找 beanId 爲 『testService』且類型爲『TestService.class』的 bean
@Resource(name = "testService",type = TestService.class)
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
注:Resource 也可以使用 @Qualifier,但是 Resource 本身可以設置 name 屬性,再使用@Qualifier多餘,所以一般沒人這樣用的
@Qualifier、@Primary
@Qualifier(“xxxx”):幫助註解 byName
@Primary:用在聲明註解,在注入接口,且接口有多個實現類,在無法唯一判斷注入哪個具體的實現類時,注入標記了@Primary的實現類(只能有一個實現類加入這種標記)
接口
public interface ITestService {
void judgeService();
}
service 實現類1 TestService
@Primary
@Service
public class TestService implements ITestService{
private TestDao testDao;
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 實現類2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller1
@Controller
public class TestController {
@Autowired
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
controller2
@Controller
public class TestController {
@Qualifier("testService2")
@Autowired
private ITestService iTestService;
public void testSwichService(){
iTestService.judgeService();
}
}
test
public class Cap9Test {
@Test
public void test01(){
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);
TestController testController = app.getBean(TestController.class);
testController.testSwichService();
}
}
如果執行 controller1, controller未指明具體注入哪個實現類,所以 注入標記了@Primary 的 service,最後輸出『this is service』
如果執行controller2,controller 使用@Qualifier(“testService2”),指明瞭注入的 beanId ,所以最終輸出爲『this is service2』
@Autowired和@Resource 的區別
相同點:
1.兩個都是注入 bean 的註解
2.都支持@Qualifier、@Primary 註解(看過教程說 @Resource不支持@Primary,但是經過實驗,是支持的)
不同點:
1.Autowired是 spring 的註解,Resource 是 jdk 的註解
2.Autowired有 require=false,如果找不到實現類就注入空。Resource 沒有這種屬性,找不到就報錯
3.Autowired 只能默認通過 byType注入。Resource 可以通過 name、type 屬性 來指定 byType、byName 注入。
特別的:在注入 bean 時,不管是 @Autowired、@Resource或是@Inject,都可以不靠@Qualifier、@Primary,或是@Resource的 name、type 屬性來輔助注入唯一的實現類。只需要通過注入時的變量與 註冊到 spring 容器中的 Bean Id 來對應即可,實際是利用 ByName 的屬性:
接口:
public interface ITestService {
void judgeService();
}
service 實現類1 TestService
@Service
public class TestService implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service");
}
}
service 實現類2 TestService2
@Service
public class TestService2 implements ITestService{
@Override
public void judgeService() {
System.out.println("this is service2");
}
}
controller
@Controller
public class TestController {
@Autowired
// @Resource
// @Inject
//此處的變量名,需要與想要注入的實現類的 beanId 相同
private ITestService TestService2;
public void testSwichService(){
TestService2.judgeService();
}
}
最後輸出結果:『this is service2』
未完,持續更新中。。。。。。