以前,小白在寫代碼的工作中,想用service類的時候一直用@Autowird或者@Resource這兩個方法來注入進行使用,有一天老大說你有沒有想過爲什麼這樣就能注入service?,小白說因爲我在服務類上加了@Service,老大說你這只是看到了表象。你去看看spring容器,然後小白就寫了一篇文章記錄自己的學習過程。
小白思考第一問:spring容器是什麼?
小白就去百度查詢了這個問題:
Spring 容器是 Spring 框架的核心,是用來管理對象的。容器將創建對象,把它們連接在一起,配置它們,並管理他們的整個生命週期從創建到銷燬。
從具象化講:通過概念的描述有些同學還是一臉懵逼,在我們的項目中哪個東西是Spring容器?在java項目中,我們使用實現了org.springframework.context.ApplicationContext接口的實現類。在web項目中,我們使用spring.xml——Spring的配置文件。
從代碼上講:一個Spring容器就是某個實現了ApplicationContext接口的類的實例。也就是說,從代碼層面,Spring容器其實就是一個ApplicationContext(一個實例化對象)。
---------------------
版權聲明:本文爲CSDN博主「_Mast」的原創文章,遵循CC 4.0 by-sa版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_34598667/article/details/83245753
看了這個博主的解答,小白細細品味了一番,自己也給出了理解:spring容器可以實例化對象。
小白第二問:怎麼用spring容器實例化對象?
小白聽了熱血沸騰,原來還能這樣來獲得實例,馬上開始打開idea開始寫測試用例。小白寫了個Service和test測試類,我偷偷去複製粘貼給大家看一下。
@Service
public class AddService {
public int add(int a,int b){
return a+b;
}
}
我偷偷把原來小白怎麼用的方式粘貼一下,這麼用是完全沒有問題的
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
@Autowired
private AddService addService2;
@Test
public void add() throws Exception {
addService2.add(1,2);
}
}
小白想了想還是有地方不明白,從容器中通過什麼來獲取實例。正在小白百思不得其姐的時候,老大剛好看到並順便提醒小白,想想自動注入的時候什麼是一直不變的,小白順着老大給的提示去網上找了找,原來是通過類名去獲取bean實例。
解答2:看看怎麼從spring容器中獲得實例
這是小白想明白之後寫的代碼,我們一起看一下。(有人很好奇,我是誰,我是解說員啊!!!解說小白菜鳥的一生)
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
private static ApplicationContext applicationContext;
@Test
public void add() throws Exception {
//去spring容器中獲取對象
AddService addService = (AddService) applicationContext.getBean("addService");
System.out.println(addService.add(1,3));
System.out.println(addService.getClass());
}
}
小白很激動的開始運行,然我們來看看結果
小白看到空指針,心裏熱血沸騰,踢開自己的牛,自己梗了二里地,然後冷靜下來,小白用dubug模式發現是因爲applicationContext是空的,這時候老大悄悄咪咪的站了出來,原來老大一直沒走,默默的看小白操作。老大看到告訴小白:“小白呀小白,想想是不是spring容器在你用的時候沒有初始化,我上次教過你用@Component將bean初始化,你想想怎麼用?”,小白也是聰明,瞬間明白了老大的意思,然後寫了個工具類,然後對測試用例做了些許調整又開始測試。然我們看一下工具類
@Component
public class SpringUtils implements BeanFactoryAware, ApplicationContextAware {
private static Logger log = LoggerFactory.getLogger(SpringUtils.class);
private static BeanFactory beanFactory;
private static ApplicationContext applicationContext;
/**
* 通過bean的id從上下文中拿出該對象
*/
public static Object getBean(String beanId) {
return beanFactory == null ? applicationContext.getBean(beanId) : beanFactory.getBean(beanId);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SsoApplication.class)
public class AddServiceTest {
@Test
public void add() throws Exception {
//去spring容器中獲取對象
AddService addService = (AddService) SpringUtils.getBean("addService");
System.out.println(addService.add(1,3));
System.out.println(addService.getClass());
}
小白很激動的點了運行,我們來看看運行結果
“哇,居然真的可以耶”,小白激動的又去梗了二里地。
至此,spring容器我們就簡單的介紹至此,小白用的是springboot1.5.9的版本。
然後老大提出幾個問題讓小白私下思考:什麼方式可以將bean放到spring容器中?spring容器能存放哪些東西?小白今天梗了幾裏地?
補充一下:SpringUtils還得繼承兩個接口,實現裏面兩個方法;
好了,今天小白的學習到此告一段落,大家想對小白有更多的瞭解,請關注我。也可以將老大提的幾個問題在評論區討論。