Spring經過大神們的構思、編碼,日積月累而來,所以,對其代碼的理解也不是一朝一夕就能快速完成的。源碼學習是枯燥的,需要堅持!堅持!堅持!當然也需要技巧,第一遍學習的時候,不用關註全部細節,不重要的代碼可以先忽略掉,達到理解大體的架子及流程,避免第一次就陷入某個坑裡出不來。第二遍針對某個流程更深入 ...
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的實例),之後就可以直接使用了。
上面只是一個簡單的描述,其中的實現過程還是很複雜的,後續篇幅將深入代碼分析具體的實現過程,分析的內容不局限於IOC、AOP、事務處理、SpringMVC,內容來自於筆者的理解及分析,如有錯誤之處還請鞭策(吐槽)。