-
我們知道Spring框架提供基于依賴注入的IOC容器,完成對象的構造、依賴注入、對象聲明周期維護等功能,下面將以FileSystemXmlApplicationContext為例來分析Spring IOC容器的實現(xiàn)。
1.容器類圖
從整體上看Spring容器可以分為兩大部分:外部容器和內(nèi)部容器。我們經(jīng)常使用的FileSystemXmlApplicationContext、ClassPathXmlApplicationContext表現(xiàn)為外部容器,他們的父類都繼承了ResourceLoader(資源加載),因此他們主要側重于對外部資源的注入、解釋方面的處理,而對于對象的構造、注入等聲明周期維護則委托給內(nèi)部對象實現(xiàn),通過區(qū)分外部容器和內(nèi)部容器,可以有效保護內(nèi)部容器管理的bean,防止外部錯誤的調(diào)用破壞對象狀態(tài)。
圖-1 外部容器類圖
圖2 內(nèi)部容器類圖
從類圖分析可以看到Spring的IOC容器可以分成兩部分:外部容器和內(nèi)部容器。外部容器主要負責與外部的調(diào)用進行溝通,包括接收外部的配置信息、為外部提供受容器管理的Bean、外部配置信息的解釋、BeanDefinition的緩存等。內(nèi)部容器主要負責Bean的聲明周期管理,包括Bean的注冊、Bean的緩存、Bean的銷毀等。
1.1 接口和類說明
類圖中列出了多種類和接口,下面列出重點的進行說明。注意官方說明,翻譯自API。
接口ListableBeanFactory官方說明
BeanFactory接口的擴展,由那些能夠列舉它們所管理的所有bean實例的bean工廠所實現(xiàn)。而不是試圖通過來自于客戶端的by name方式的bean查找。預載所有bean definitions的BeanFactory實現(xiàn)可能會實現(xiàn)該接口。
個人理解
:提供bean factory所管理bean的枚舉的接口
接口HierarchicalBeanFactory
官方說明
由bean factory實現(xiàn)的子接口,實現(xiàn)了該接口的bean factory能成為一個層次結構的一部分。
個人理解:用以組織bean factory層次的一個接口。
接口ApplicationContext
官方說明:
中心接口,以提供應用程序的配置。當應用程序正在運行,這是只讀的,但如果實現(xiàn)支持,它是允許重新加載的。
一個ApplicationContext提供如下功能:
用來訪問應用程序組件的bean factory方法,其繼承自ListableBeanFactory。
能以通用的方式加載文件資源,其繼承自ResourceLoader。
能夠向注冊的監(jiān)聽器發(fā)布事件,其繼承自ApplicationEventPublisher。
能夠解析消息,支持國際化,繼承自MessageSource。
繼承自父上下文,后代上下文中的Definition將總能獲得優(yōu)先級,這意味著,例如,一個單親上下文能夠被整個應用程序使用,而每個servlet有它自己的孩子上下文,它獨立于其他的servlet。
接口AutowireCapableBeanFactory
官方說明
BeanFactory接口的擴展,可以被那些有能力自動裝配的bean factory實現(xiàn),用以達到為存在的bean暴露此項功能的目的。
該接口不應在常見的應用程序中使用,黏合BeanFactory或者ListableBeanFactory是其典型的應用案例。
應該注意的是,該接口不應被ApplicationContext直接實現(xiàn),因為應用程序代碼幾乎不曾被應用程序代碼使用。也就是說,它也可以通過訪問ApplicationContext的getAutowireCapableBeanFactory()方法從應用程序上下文中獲得,即獲得一個AutowireCapableBeanFactory實例。
個人理解從接口定義的方法中可以看出,該接口主要用于自動裝配bean,包括創(chuàng)建bean、裝配bean的屬性、裝配bean的依賴、注冊bean等。該接口對于外部的應用程序而言,幾乎不需要使用,其只應用于Spring容器的內(nèi)部管理,實際上只有內(nèi)部bean factory實現(xiàn)此功能。關于內(nèi)部bean factory后面會有說明。
接口ConfigurableApplicationContext官方說明
SPI(單個程序啟動)接口將會被大多數(shù)而不是全部的應用程序上下文實現(xiàn),除了在ApplicationContext中的應用程序上下文客戶端方法,其還提供設施來配置上下文。
配置和生命周期方法被封裝在這里,以避免使他們暴漏給ApplicationContext的客戶端代碼。這些方法應該只用于啟動和關閉代碼中。
個人理解:
抽象類AbstractApplicationContext官方說明:
ApplicationContext接口的抽象實現(xiàn)。其不要求配置使用的存儲類型,只是簡單的實現(xiàn)了常見上下文功能。它采用了模板方法模式,因此要求具體子類實現(xiàn)抽象方法。
與普通的BeanFactory相比,ApplicationContext支持檢測定義在其內(nèi)部的bean工廠中的特殊的bean。因此,該類能自動注冊BeanFactoryPostProcessor、BeanPostProcessor、ApplicationListener,它們在上下文中都被定義為beans。
通過擴展DefaultResourceLoader實現(xiàn)資源加載,因此,視非URL資源路徑為類路徑資源(支持完整類路徑資源命名,包括包路徑,例如mypackage/myresource.dat),否則getResourceByPath方法需要在子類中覆寫。
個人理解:
該類提供了BeanFactory的后置processor的注冊、應用上下文的雙親維護、資源加載的功能。
抽象類AbstractRefreshableApplicationContextApplicationContext的基類的實現(xiàn),其支持多次refreshs,每次創(chuàng)建一個內(nèi)部bean工廠實例。通常(但不一定),一個上下文將會由一系列的配置定位來驅動,加載bean definations。
子類唯一需要實現(xiàn)的方法是loadBeanDefinitions,該方法主要是獲取每次刷新調(diào)用。具體的實現(xiàn)應該是加載bean定義到給定的org.springframework.beans.factory.support.DefaultListableBeanFactory,通常委托給一個或多個特定的bean definition readers。
抽象類AbstractRefreshableConfigApplicationContext官方說明
AbstractRefreshableApplicationContext的子類,增加了針對 指定的配置位置(configLocations)的常見的處理。可以作為基于XML應用程序上下文實現(xiàn)的基類,例如ClassPathXmlApplicationContex與FileSystemXmlApplicationContext,也可以是XmlWebApplicationContext與XmlPortletApplicationContext。
個人理解:主要為配置文件位置的設置提供入口,即實現(xiàn)了setConfigLocation方法。這就提供了不依賴于Spring的且更靈活、通用的配置注入方式。
抽象類AbstractXmlApplicationContext說明:ApplicationContext的便利基類的實現(xiàn)。用于提取包含bean definition信息的XML文檔,該文檔由XmlBeanDefinitionReader負責解釋。
子類要實getConfigResources和/或getConfigLocations,此外,他們可能會覆蓋
getResourceByPath鉤子來解釋相對路徑。類FileSystemXmlApplicationContext說明
獨立的XML應用程序上下文,它從文件系統(tǒng)或者URLs獲得上下文定義,解釋普通路徑為相對文件系統(tǒng)位置(如“MYDIR/ myfile.txt”),同時它也是有用的測試工具與獨立環(huán)境。
普通路徑總是會被解釋為相對當前VM的工作目錄,即使他們以斜線開頭。(這與Servlet容器的語義是一致的。)使用一個明確的“file:”前綴,以執(zhí)行一個絕對文件路徑。
配置文件位置默認值可以通過getConfigLocations覆蓋,配置位置可以表示為“/ MYFILES/ context.xml中”之類的具體文件,也可以像“/ MYFILES/ *- context.xml”似的Ant風格模式(org.springframework.util.AntPathMatcher)。
注意:在多個配置位置的情況下,以后的bean定義覆蓋先前加載的文件中定義的。這可以通過一個額外的XML文件,來故意覆蓋某些bean定義。
這是一個簡單的,一站式的便利的ApplicationContext。考慮結合使用GenericApplicationContext和XmlBeanDefinitionReader提供更靈活的上下文設置。
接口ResourceLoader加載資源(例如,類路徑和文件路徑)的策略接口,ApplicationContext需要提供此功能,加上擴展的ResourcePatternResolver支持。DefaultResourceLoader是該接口的獨立實現(xiàn),它可用于ApplicationContext以外,也可以被ResourceEditor使用。
接口ResourcePatternResolver解釋位置模式的策略接口,其擴展自ResourcePatternResolver接口。
類PathMatchingResourcePatternResolverResourcePatternResolver接口的實現(xiàn),能夠把指定的資源位置路徑轉化為一個或者多個匹配資源。源路徑可能是一個簡單的路徑,它一對一映射到目標(Resource),或者可能選擇性地包含特定的“classpath*:”前綴和/或者Ant-style正則表達式(由org.springframework.util.AntPathMatcher匹配)
在一般的情況,如果指定的位置路徑?jīng)]有以“classpath*:”前綴開始,并且未包含PathMatcher模式,解釋器將通過調(diào)用ResourceLoader的getResource方法返回單一的資源。例子可包括真實的 URLs,例如file:C:/context.xml;偽URLs,例如classpath:/context.xml;簡單的無前綴的路徑,例如,/WEB-INF/context.xml。
2容器啟動分析
2.1容器的構建
我們以FileSystemXmlApplicationContext為例來分析容器的啟動過程,首先看看FileSystemXmlApplicationContext的構造函數(shù):public FileSystemXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
//refresh方法是容器啟動的核心,包括內(nèi)部容器的維護,資源定位處理,資源的解析、注冊等。
refresh();
}
}
關于super的調(diào)用,以下代碼是個重點:
以下代碼來自于AbstractApplicationContext,這里要注意的是容器在構造時自動構造了資源模式解釋器,關于資源模式解釋器后面會有介紹.
//資源模式解釋器,用于解釋處理ant-style配置信息,也可以把它理解為批量資源解釋器,并把解釋的一組資源定位解釋成Resource.該實例在容器創(chuàng)建時會自動創(chuàng)建
private ResourcePatternResolver resourcePatternResolver;
public AbstractApplicationContext(ApplicationContext parent) {
this.parent = parent;
this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
一般情況下,我們可以通過編碼的方式來啟動容器,例如,如下:
ApplicationContext context = new FileSystemXmlApplicationContext (
new String[] {"classpath:applicationContext*.xml"},true,null);
BeanFactory factory = (BeanFactory) context;
2.2容器的初始化
2.2.1Refresh方法分析
我們接下來分析fresh方法,該方法由FileSystemXmlApplicationContext的父類AbstractApplicationContext實現(xiàn),從圖1可以看到AbstractApplicationContext是ApplicationContext接口的最頂層實現(xiàn)。public void refresh() throws BeansException, IllegalStateException {
//獲得啟動關閉監(jiān)視器,防止此刻容器被其他線程操作。
synchronized (this.startupShutdownMonitor) {
prepareRefresh();//激活容器的活動狀態(tài),采用鎖進行同步
/**這里是容器初始化最為關鍵的一步,主要完成:
1.內(nèi)部容器的初始化,包括對已經(jīng)存在的內(nèi)部容器管理的資源的銷毀、內(nèi)部容器的銷毀、創(chuàng)建新的內(nèi)部容器等;
2.資源定位解釋,即把configLocations解釋成一個或者多個Resource;
3.BeanDefinition加載與注冊,把Resource加載解釋成xml Document,然后對Document進行解釋,形成BeanDefinition,并對Definition進行注冊;*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//內(nèi)部工廠的預處理,主要是注冊一些Spring組件
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
//調(diào)用BeanFactory的后置處理,其處理的流程是:
/**
(1)先對在prepareBeanFactory階段注冊的后置處理組件先進行調(diào)用;
(2)然后從容器加載BeanFactoryPostProcessor類型的bean,進行調(diào)用處理,這類例子我們經(jīng)常用到,例如PropertyPlaceholderConfigurer在分離數(shù)據(jù)庫配置中的使用;*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
beanFactory.destroySingletons();
cancelRefresh(ex);
throw ex;
}
}
}
2.2.2 obtainFreshBeanFactory方法分析以下代碼來自于AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
……
return beanFactory;
}
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
從代碼中可以看到方法refreshBeanFactory與getBeanFactory都被定義為抽象方法,這是典型的模板方法模式。其中子類AbstractRefreshableApplicationContext與GenericApplicationContext都實現(xiàn)這些方法,接下來以AbstractRefreshableApplicationContext的實現(xiàn)作進一步說明。
2.2.2.1 refreshBeanFactory方法分析refreshBeanFactory方法代碼:
/** Bean factory for this context */
//上下文中的beanFactory,這個factory就是所的內(nèi)部容器,可以在圖2中看到它的繼承關系
private DefaultListableBeanFactory beanFactory;
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {//檢查beanFactory是否為空,如果不為空,則銷毀singletonBeans緩存、singletonFactories工廠緩存、beanFactory等;
destroyBeans();
closeBeanFactory();
}
try {
// 創(chuàng)建internal bean factory,即屬性beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory(); customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);// 加載BeanDefinition,下面重點討論的
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException(
"I/O error parsing XML document for application context [" + getDisplayName() + "]", ex);
}
}
容器可以有雙親(AbstractApplicationContext類的parent),每個容器下都有一個beanFactory(AbstractRefreshableApplicationContext下),該beanFactory的類型為DefaultListableBeanFactory,我們稱之為內(nèi)部容器。它才是真正意義上bean的管理容器,因為緩存相關bean的信息的載體是由其父類DefaultSingletonBeanRegistry負責的,這一點在下面的destroyBeans方法分析中將能看到。
refreshBeanFactory()方法詳細說明:
<1>檢查內(nèi)部的beanFactory是否存在,如果存在則要銷毀beanFactory內(nèi)存在的相關資
源(關于銷毀的資源參看destroyBeans方法的說明)以及關閉beanFactory;
<2>構造新的內(nèi)部bean factory,并定制該工廠,定制的選項主要包括:allowBeanDefinitionOverriding(是否允許bean definition覆蓋)
allowCircularReferences(是否允許bean之間循環(huán)引用)
<3>加載bean definition;
destroyBeans()方法解析
在解析之前我們先明確一件事情,spring把bean分為單實例(singleton)與原型(prototype)兩種類型。對于singleton類型的bean,容器只保留一個實例,而原型類型的bean是容器每次接受請求通過defination創(chuàng)建的一個新實例。因此,我們都能夠推斷出容器是要緩存singleton bean的,事實上spring也確實這樣做的。
destroyBeans主要完成了以下任務,銷毀singleton beans、early singleton beans、singleton factory beans、disposable beans以及disposable beans的依賴beans。destroyBeans方法由DefaultListableBeanFactory的父類DefaultSingletonBeanRegistry實現(xiàn)的,包括對singleton beans的相關緩存實現(xiàn),其代碼如下:
protected void destroyBeans() {
getBeanFactory().destroySingletons();//destroySingletons()的實現(xiàn)在下面
//這里的getBeanFactory()獲得的是上面提到的內(nèi)部容器beanFactory
}
/*************以下代碼摘自DefaultSingletonBeanRegistry**********/
//緩存singleton對象集合,映射關系為bean name--> bean instance
/**ConcurrentMap的創(chuàng)建:jdk5以及以上使用juc包的ConcurrentMap;否則,存在edu的ConcurrentMap則使用edu的ConcurrentMap,否則使用Collection.synchronizedMap(HashMap);*/
private final Map singletonObjects = CollectionFactory.createConcurrentMapIfPossible(16);
/** Cache of singleton factories: bean name --> ObjectFactory */
/**緩存singleton factory bean集合,這是不是說明一個singleton的beanName需要對應一個真實的singleton bean以及一個singleton factory bean呢?答案是否定的,F(xiàn)actoryBean存在的意義在于:在開發(fā)中可能存在需要類似于工廠模式創(chuàng)建類的需求,即一個對象是由工廠代理創(chuàng)建的,尤其是在第三方庫結合的時候,可以用FactoryBean來創(chuàng)建合適的bean.*/
private final Map singletonFactories = new HashMap();
/** Cache of early singleton objects: bean name --> bean instance */
//緩存早期的singlton bean,那么早期是如何定義的呢?spring又是如何管理的呢?
private final Map earlySingletonObjects = new HashMap();
/** Set of registered singletons, containing the bean names in registration order */
//注冊的singleton bean集合,主要包含以注冊順序存儲的bean names
private final Set registeredSingletons = new LinkedHashSet(16);
/** Names of beans that are currently in creation */
//當前創(chuàng)建的singleton bean的name
private final Set singletonsCurrentlyInCreation = Collections.synchronizedSet(new HashSet());
/** List of suppressed Exceptions, available for associating related causes */
private Set suppressedExceptions;
/** Flag that indicates whether we're currently within destroySingletons */
//表示當前是否處于銷毀singleton的狀態(tài)
private boolean singletonsCurrentlyInDestruction = false;
/** Disposable bean instances: bean name --> disposable instance */
//處置bean,主要在bean銷毀時需要調(diào)用該bean的destroy方法,即實現(xiàn)了disposable接口
private final Map disposableBeans = new LinkedHashMap(16);
/** Map between dependent bean names: bean name --> Set of dependent bean names */
//用于保存bean的依賴關系,即一個bean依賴于哪幾個bean
private final Map dependentBeanMap = CollectionFactory.createConcurrentMapIfPossible(16);
//上一個的反向存儲,可以理解為從屬于
/** Map between depending bean names: bean name --> Set of bean names for the bean's dependencies */
private final Map dependenciesForBeanMap = CollectionFactory.createConcurrentMapIfPossible(16);
public void destroySingletons() {//銷毀單例
synchronized (this.singletonObjects) {
this.singletonsCurrentlyInDestruction = true;
}
synchronized (this.disposableBeans) {
String[] disposableBeanNames = StringUtils.toStringArray(this.disposableBeans.keySet());
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
destroySingleton(disposableBeanNames[i]);
}
}
synchronized (this.singletonObjects) {
this.singletonObjects.clear(); //清除singleton對象
this.singletonFactories.clear();//清除single factory bean
this.earlySingletonObjects.clear();//清除早期的single對象
this.registeredSingletons.clear();
this.singletonsCurrentlyInDestruction = false;
}
}
下一頁
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
27 | 28 | 29 | 30 | 1 | 2 | 3 | |||
4 | 5 | 6 | 7 | 8 | 9 | 10 | |||
11 | 12 | 13 | 14 | 15 | 16 | 17 | |||
18 | 19 | 20 | 21 | 22 | 23 | 24 | |||
25 | 26 | 27 | 28 | 29 | 30 | 31 | |||
1 | 2 | 3 | 4 | 5 | 6 | 7 |
常用鏈接
留言簿(1)
隨筆分類(17)
- arithmetics(3)
- C/C++(1)
- Cache
- DB(1)
- IOC/AOP(2)
- java concurrency(2)
- java 多線程
- JDK(1)
- JVM(1)
- Linux(1)
- nosql(5)
- Performance
隨筆檔案(28)
- 2014年7月 (3)
- 2014年5月 (1)
- 2014年4月 (1)
- 2013年6月 (1)
- 2013年4月 (2)
- 2013年3月 (1)
- 2012年8月 (1)
- 2012年5月 (1)
- 2012年2月 (6)
- 2012年1月 (1)
- 2011年10月 (1)
- 2011年9月 (1)
- 2011年6月 (2)
- 2009年8月 (3)
- 2008年5月 (1)
- 2006年4月 (2)
文章分類(30)
- AJAX
- common(3)
- DB(3)
- java tools(1)
- JAVA 基礎文章(1)
- java 并發(fā)(3)
- JDBC(1)
- linux(3)
- ORM(包括hibernate等)(2)
- Spring(6)
- SWT、SWING、AWT(2)
- web(2)
- web service
- 優(yōu)化(2)
- 版本控制(1)
文章檔案(30)
- 2013年4月 (1)
- 2013年3月 (1)
- 2012年1月 (2)
- 2011年12月 (1)
- 2011年11月 (1)
- 2011年8月 (2)
- 2011年7月 (1)
- 2011年6月 (4)
- 2011年4月 (3)
- 2009年8月 (4)
- 2008年6月 (1)
- 2008年4月 (1)
- 2007年3月 (2)
- 2006年12月 (1)
- 2006年10月 (2)
- 2006年8月 (1)
- 2006年6月 (1)
- 2006年4月 (1)
相冊
收藏夾(2)
hibernate
java基礎
mysql
xml
- IBM XSL
- w3c標準的xpath說明
- web service ibm
- XPath 示例
- XPath 簡單語法
- XQuery 1.0 and XPath 2.0 Full-Text Use Cases
關注
壓力測試
算法
最新隨筆
- 1.?解決Redis數(shù)據(jù)庫響應延遲問題(轉載)
- 2.?理想化的 Redis 集群 (轉載)
- 3.?Redis 分區(qū)(翻譯)
- 4.?Mysql索引相關知識分享
- 5.?數(shù)據(jù)結構-BinaryTree
- 6.?深入學習Linux之命令篇-find
- 7.?什么情況下應該使用GridFS(翻譯)
- 8.?Mongodb主從復制實踐
- 9.?jmap使用
- 10.?為什么實現(xiàn)了equal方法,一定需要實現(xiàn)hashCode方法呢?
- 11.?MongoDB學習—MongoDB安裝
- 12.?京東碰到的一道面試題
- 13.?HashMap分析
- 14.?12個小球其中有一個是次品,不過不知道輕重,請問用天平能用三次測量的機會找出那個次品嗎?
- 15.?使用java nio 實現(xiàn) Ping
- 16.?Spring 源碼閱讀(IOC容器)-容器啟動2
- 17.?Spring 源碼閱讀(IOC容器)-容器啟動1
- 18.?JDBC SavePoint淺析
- 19.?Linux下C訪問MySQL實踐
- 20.?Apache Benchmark(ab)使用
- 21.?Java NIO Demo
- 22.?Amoeba源碼解讀一
- 23.?編寫跨平臺代碼注意事項
- 24.?編寫跨平臺代碼注意事項
- 25.?JavaScript的toString()方法自動調(diào)用
搜索
積分與排名
- 積分 - 96364
- 排名 - 601
最新評論

- 1.?嗯嗯
- 阿斯達斯
- --安德森
- 2.?re: tomcat 產(chǎn)生heapdump文件配置
- 如果不內(nèi)存溢出,heapdump目錄是不是空的?
- --小龍在線
- 3.?re: Java NIO Demo
- 評論內(nèi)容較長,點擊標題查看
- --zuidaima
- 4.?re: Redis 分區(qū)(翻譯)
- 手機賺錢軟件http://www.szapk.cn!!!
- --手機賺錢軟件http://www.szapk.cn
- 5.?re: Mysql索引相關知識分享
- 很有價值的分享,值得學習
- --任務大廳
閱讀排行榜
評論排行榜
- 1.?Mysql索引相關知識分享(4)
- 2.?京東碰到的一道面試題(1)
- 3.?Linux下C訪問MySQL實踐(1)
- 4.?Apache Benchmark(ab)使用(1)
- 5.?Java NIO Demo(1)
- 6.?JavaScript的toString()方法自動調(diào)用(1)
- 7.?lucene 實踐(1)
- 8.?Redis 分區(qū)(翻譯)(1)
- 9.?解決Redis數(shù)據(jù)庫響應延遲問題(轉載)(0)
- 10.?理想化的 Redis 集群 (轉載)(0)
- 11.?dom4j學習筆記(0)
- 12.?創(chuàng)建mysql innodb數(shù)據(jù)庫(0)
- 13.?Amoeba源碼解讀一(0)
- 14.?編寫跨平臺代碼注意事項(0)
- 15.?編寫跨平臺代碼注意事項(0)
- 16.?HashMap分析(0)
- 17.?12個小球其中有一個是次品,不過不知道輕重,請問用天平能用三次測量的機會找出那個次品嗎?(0)
- 18.?使用java nio 實現(xiàn) Ping(0)
- 19.?Spring 源碼閱讀(IOC容器)-容器啟動2(0)
- 20.?Spring 源碼閱讀(IOC容器)-容器啟動1(0)