Spring 經過大神們的構思、編碼,日積月累而來,所以,對其代碼的理解也不是一朝一夕就能快速完成的。源碼學習是枯燥的,需要堅持!堅持!堅持!當然也需要技巧.
第一遍學習的時候,不用關注全部細節,不重要的代碼可以先忽略掉,達到理解大體的架子及流程,避免第一次就陷入某個坑里出不來。
第二遍針對某個流程更深入的、有針對性的去分析學習,當然遇到某個實在過不去的坎可以標記,后面再思考,畢竟是別人設計的,有些不是那么容易理解,可以使用 google,次數多了,總會有收獲!
首先,看一下 Spring 的最基本使用方式,直接看代碼,
public class LoginService {
public void login() {
System.out.println("execute LoginService");
}
}
public class LoginResource {
private LoginService loginService;
public LoginService getLoginService() {
return loginService;
}
public void setLoginService(LoginService loginService) {
this.loginService = loginService;
}
public void login() {
loginService.login();
}
}
applicationgContext.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
">
<bean id="loginService" name="loginService" class="spring.LoginService"/>
<bean id="loginResource" name="loginResource" class="spring.LoginResource">
<property name="loginService" ref="loginService"/>
</bean>
</beans>
public class TestClient {
@Test
public void test() {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationgContext.xml");
LoginResource loginResource = (LoginResource) applicationContext.getBean("loginResource");
loginResource.login();
}
}
概括的描述一下 Spring 背后的操作,解析 applicationgContext.xml,將 xml 中定義的 bean(如 loginService 和 loginResource) 解析成 Spring 內部的 BeanDefinition,並以 beanName(如 loginService) 為 key,BeanDefinition(如 loginService 相應的 BeanDefinition) 為 value 存儲到 DefaultListableBeanFactory 中的 beanDefinitionMap (其實就是一個 ConcurrentHashMap) 中,同時將 beanName 存入 beanDefinitionNames(List 類型) 中,然后遍歷 beanDefinitionNames 中的 beanName,進行 bean 的實例化並填充屬性,在實例化的過程中,如果有依賴沒有被實例化將先實例化其依賴,然后實例化本身,實例化完成后將實例存入單例 bean 的緩存中,當調用 getBean 方法時,到單例 bean 的緩存中查找,如果找到並經過轉換后返回這個實例 (如 LoginResource 的實例),之后就可以直接使用了。