概述
org.springframework.context.ApplicationContext接口是Spring IoC的容器,負(fù)責(zé)bean的初始化,配置和裝配。ApplicationContext通過讀取元數(shù)據(jù)(configuration metadata)獲取該把bean注入到哪個(gè)對象皆辽。元數(shù)據(jù)可以是XML, Java注解或Java代碼。
Spring提供了幾種ApplicationContext的實(shí)現(xiàn)芥挣。本地化項(xiàng)目使用的ClassPathXMLApplicationContext或FileSystemXMLApplicationContext. 然而XML是比較傳統(tǒng)的配置方式驱闷,使用注解或代碼配合少量XML作為元數(shù)據(jù)可以使配置更精簡。
在大多數(shù)應(yīng)用場景空免,我們不需要自己去創(chuàng)建ApplicationContext的實(shí)例空另。例如在web應(yīng)用中,只需要在web.xml中增加8行配置就可以了:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/daoContext.xml /WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Figure 1. The Spring IoC container
Configuration metadata
元數(shù)據(jù)的三種配置方式:
- 完全XML
- 少量XML(component-scan) + Java注解
- Java代碼(全部使用注解)
1 spring-core 包結(jié)構(gòu)
<pre>
src
└─org
└─springframework
├─asm
├─cglib
│ └─core
├─core
│ ├─annotation
│ ├─codec
│ ├─convert
│ │ ├─converter
│ │ └─support
│ ├─env
│ ├─io
│ │ ├─buffer
│ │ └─support
│ ├─serializer
│ │ └─support
│ ├─style
│ ├─task
│ │ └─support
│ └─type
│ ├─classreading
│ └─filter
├─lang
├─objenesis
└─util
├─backoff
├─comparator
├─concurrent
└─xml
</pre>
1.1 spring-core各模塊功能說明
1.asm Spring將ASM代碼重新打包蹋砚,提供ASM依賴扼菠。
http://blog.csdn.net/whos2002110/article/details/40817939
2.cglib cglib生成的動(dòng)態(tài)代理類命名規(guī)則(className$$classNameBySpringCGLIB$$hashCode)
3.core
4.lang 條件編譯注解
5.objenesis 對象實(shí)例化工具,封裝后提供緩存功能(單例)
6.util 各種工具類
2 spring-core.core
<pre>
core
├─annotation
├─codec
├─convert
│ ├─converter
│ └─support
├─env
├─io
│ ├─buffer
│ └─support
├─serializer
│ └─support
├─style
├─task
│ └─support
└─type
├─classreading
└─filter
</pre>
2.1 annotation
注解解析器和工具類
AnnotationUtils.getAnnotationAttributes(Annotation)
AnnotationUtils.getValue(Annotation annotation, String attributeName)
2.2 codec
各種編碼解碼工具
2.3 convert
轉(zhuǎn)碼工具
2.4 env##
2.4.1 概述####
env包是Spring3.1開始提供的新的屬性管理API坝咐,提供配置讀取和環(huán)境劃分能力娇豫,主要接口:PropertySource和Environment
2.4.2 PropertySource####
PropertySource:屬性源,key-value屬性對抽象畅厢,比如用于配置數(shù)據(jù)
PropertyResolver:屬性解析器冯痢,用于解析相應(yīng)key的value
2.4.2.1主要實(shí)現(xiàn)類#####
MapPropertySource:屬性來自于一個(gè)Map
ResourcePropertySource:屬性來自于一個(gè)properties文件
ServletContextPropertySource:屬性來自ServletContext上下文初始化參數(shù)
CompositePropertySource:提供了組合PropertySource的功能,查找順序就是注冊順序。
2.4.3 Environment####
Environment:環(huán)境浦楣,本身是一個(gè)PropertyResolver袖肥,但是提供了Profile特性,即可以根據(jù)環(huán)境得到相應(yīng)數(shù)據(jù)(即激活不同的Profile振劳,可以得到不同的屬性數(shù)據(jù)椎组,比如用于多環(huán)境場景的配置(正式機(jī)、測試機(jī)历恐、開發(fā)機(jī)DataSource配置))
Profile:剖面寸癌,Environment使Spring具有了剖面特性,只有激活的剖面的組件/配置才會(huì)注冊到Spring容器弱贼,類似于maven中profile蒸苇。這是context包中的一個(gè)注解。另外context包中還有一個(gè)叫做EnviromentAware的類吮旅,ApplicationContext是其子類溪烤,因此我們在SpringContext中可以獲取所有的配置和Profile信息。
@Inject Environment environment;
environment.getProperty( AppConfig.SERVER_HOST ),
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
if (logger.isInfoEnabled()) {
logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec +
"] not matching: " + getReaderContext().getResource());
}
return;
}
2.5 io##
2.5.1 概述####
在日常程序開發(fā)中庇勃,處理外部資源是很繁瑣的事情檬嘀,我們可能需要處理URL資源、File資源資源责嚷、ClassPath相關(guān)資源鸳兽、服務(wù)器相關(guān)資源(JBoss AS 5.x上的VFS資源)等等很多資源。因此處理這些資源需要使用不同的接口罕拂,這就增加了我們系統(tǒng)的復(fù)雜性揍异;而且處理這些資源步驟都是類似的(打開資源、讀取資源聂受、關(guān)閉資源)蒿秦,因此如果能抽象出一個(gè)統(tǒng)一的接口來對這些底層資源進(jìn)行統(tǒng)一訪問,是不是很方便蛋济,而且使我們系統(tǒng)更加簡潔棍鳖,都是對不同的底層資源使用同一個(gè)接口進(jìn)行訪問。
spring提供一個(gè)Resource接口來統(tǒng)一這些底層資源一致的訪問碗旅,而且提供了一些便利的接口渡处,從而能提供我們的生產(chǎn)力。
2.5.2 Resource接口####
Spring的Resource接口代表底層外部資源祟辟,對JDK InputStream的擴(kuò)展医瘫,提供了對底層外部資源的一致性訪問接口。
2.5.3 主要實(shí)現(xiàn)類####
2.5.3.1 ByteArrayResource#####
ByteArrayResource代表byte[]數(shù)組資源旧困,對于“getInputStream”操作將返回一個(gè)ByteArrayInputStream醇份。ByteArrayResource可多次讀取數(shù)組資源稼锅,即isOpen ()永遠(yuǎn)返回false。
2.5.3.2 InputStreamResource#####
InputStreamResource代表java.io.InputStream字節(jié)流僚纷,對于“getInputStream ”操作將直接返回該字節(jié)流矩距,因此只能讀取一次該字節(jié)流,即“isOpen”永遠(yuǎn)返回true怖竭。
2.5.3.4 FileSystemResource
FileSystemResource代表java.io.File資源锥债,對于“getInputStream ”操作將返回底層文件的字節(jié)流,“isOpen”將永遠(yuǎn)返回false痊臭,從而表示可多次讀取底層文件的字節(jié)流哮肚。
2.5.3.5 ClassPathResource
ClassPathResource代表classpath路徑的資源,將使用ClassLoader進(jìn)行加載資源广匙。classpath 資源存在于類路徑中的文件系統(tǒng)中或jar包里允趟,且“isOpen”永遠(yuǎn)返回false,表示可多次讀取資源艇潭。
ClassPathResource加載資源替代了Class類和ClassLoader類的“getResource(String name)”和“getResourceAsStream(String name)”兩個(gè)加載類路徑資源方法拼窥,提供一致的訪問方式戏蔑。
ClassPathResource提供了三個(gè)構(gòu)造器:
public ClassPathResource(String path):使用默認(rèn)的ClassLoader加載“path”類路徑資源蹋凝;
public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加載“path”類路徑資源;
比如當(dāng)前類路徑是“cn.javass.spring.chapter4.ResourceTest”总棵,而需要加載的資源路徑是“cn/javass/spring/chapter4/test1.properties”鳍寂,則將加載的資源在“cn/javass/spring/chapter4/test1.properties”;
public ClassPathResource(String path, Class<?> clazz):使用指定的類加載“path”類路徑資源情龄,將加載相對于當(dāng)前類的路徑的資源迄汛;
2.5.3.6 UrlResource#####
UrlResource代表URL資源,用于簡化URL資源訪問骤视“鞍“isOpen”永遠(yuǎn)返回false,表示可多次讀取資源专酗。
UrlResource一般支持如下資源訪問:
http:通過標(biāo)準(zhǔn)的http協(xié)議訪問web資源睹逃,如new UrlResource(“http://地址”);
ftp:通過ftp協(xié)議訪問資源祷肯,如new UrlResource(“ftp://地址”)沉填;
file:通過file協(xié)議訪問本地文件系統(tǒng)資源,如new UrlResource(“file:d:/test.txt”)佑笋;
2.5.3.7 ServletContextResource#####
ServletContextResource代表web應(yīng)用資源翼闹,用于簡化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作;
2.5.4 ResourceLoader接口####
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
getResource接口用于根據(jù)提供的location參數(shù)返回相應(yīng)的Resource對象蒋纬;而getClassLoader則返回加載這些Resource的ClassLoader猎荠。
Spring提供了一個(gè)適用于所有環(huán)境的DefaultResourceLoader實(shí)現(xiàn)坚弱,可以返回ClassPathResource、UrlResource关摇;還提供一個(gè)用于web環(huán)境的ServletContextResourceLoader史汗,它繼承了DefaultResourceLoader的所有功能,又額外提供了獲取ServletContextResource的支持拒垃。
ResourceLoader在進(jìn)行加載資源時(shí)需要使用前綴來指定需要加載:“classpath:path”表示返回ClasspathResource停撞,“http://path”和“file:path”表示返回UrlResource資源,如果不加前綴則需要根據(jù)當(dāng)前上下文來決定悼瓮,DefaultResourceLoader默認(rèn)實(shí)現(xiàn)可以加載classpath資源戈毒。
2.6 serializer##
序列化和反序列化
public interface Serializer<T> {
void serialize(T object, OutputStream outputStream) throws IOException;
}
public interface Deserializer<T> {
T deserialize(InputStream inputStream) throws IOException;
}
2.7 style
格式化輸出工具類
···
public interface ValueStyler {
String style(Object value);
}
public interface ToStringStyler {
void styleStart(StringBuilder buffer, Object obj);
void styleEnd(StringBuilder buffer, Object obj);
void styleField(StringBuilder buffer, String fieldName, Object value);
void styleValue(StringBuilder buffer, Object value);
void styleFieldSeparator(StringBuilder buffer);
}
···
2.8 task
2.8.1 概述####
Java SE 5.0引入了ThreadPoolExecutor、ScheduledThreadPoolExecutor横堡。Spring 2.x借助ConcurrentTaskExecutor和ThreadPoolTaskExecutor能夠通過IoC配置形式自定義它們暴露的各個(gè)屬性埋市。
TaskExecutor接口,是對java.util.concurrent.Executor接口的擴(kuò)展命贴。給其他組件提供線程池的抽象道宅。
例如ApplicationEventMulticaster組件、JMS的AbstractMessageListenerContainer和對Quartz的整合都使用了TaskExecutor抽象來提供線程池胸蛛。
2.8.2 配置與使用####
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心線程數(shù) -->
<property name="corePoolSize" value="5" />
<!-- 最大線程數(shù) -->
<property name="maxPoolSize" value="50" />
<!-- 隊(duì)列最大長度 -->
<property name="queueCapacity" value="1000" />
<!-- 線程池維護(hù)線程所允許的空閑時(shí)間污茵,默認(rèn)為60s -->
<property name="keepAliveSeconds" value="60" />
</bean>
@Resource(name = "taskExecutor")
private TaskExecutor taskExecutor;
taskExecutor.execute(()-> {
...
});
2.8.3 實(shí)現(xiàn)類
從類圖上很明顯可以看出分為同步Executor和異步Executor。同步比較簡單葬项,就是調(diào)用一下的run方法泞当。下面主要分析異步。
- SimpleAsyncTaskExecutor:每次調(diào)用都啟動(dòng)一個(gè)新線程民珍。但是襟士,它還是支持對并發(fā)總數(shù)設(shè)限,當(dāng)超過線程并發(fā)總數(shù)限制時(shí)嚷量,阻塞新的調(diào)用陋桂,直到有位置被釋放。
- ConcurrentTaskExecutor:對Java 5 java.util.concurrent.Executor類的適配蝶溶,暴露了Executor的配置參數(shù)作為bean屬性嗜历,可以配置自己的Executor,可以設(shè)置任務(wù)裝飾器身坐。
- **ThreadPoolTaskExecutor **:對java.util.concurrent.ThreadPoolExecutor的包裝秸脱。
-
ThreadPoolTaskScheduler:對java.util.concurrent.ScheduledExecutorService的封裝,并提供了@Scheduled 注解,極大簡化了ScheduledExecutorService的操作部蛇。
使用方法:
// 修改spring context配置文件摊唇,增加xmlns和xsi
// xmlns
xmlns:task="http://www.springframework.org/schema/task"
// xsi
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.1.xsd
//增加task注解掃描
<task:annotation-driven/>
// 方法上加Scheduled 注解,支持fixedDelay涯鲁、Cron等多種方式
@Scheduled(cron="0/3 * * * * ? ") //每3秒執(zhí)行一次
public void foo(){
...
}
3.Spring-Core.utils#
<pre>
util
├─backoff
├─comparator
├─concurrent
└─xml
</pre>
3.1 backoff##
Spring封裝的退避算法巷查,用于獲取重試間隔有序。兩個(gè)實(shí)現(xiàn)類,F(xiàn)ixedBackOff是按照固定時(shí)間間隔重試岛请,ExponentialBackOff是間隔以指數(shù)方式增長旭寿。
3.2 concurrent##
Spring中對java.util.concurrent.Future的擴(kuò)展,支持Future適配崇败,F(xiàn)utureTask添加多個(gè)回調(diào)函數(shù)盅称。
3.2.1 主要類
ListenableFuture<T>:增加擴(kuò)展功能使用addCallback()方法支持增加回調(diào)函數(shù)
ListenableFutureTask<T>:FutureTask子類,主要是為了增加回調(diào)函數(shù)注冊和回調(diào)函數(shù)調(diào)用功能后室。該類重寫了done()方法缩膝,執(zhí)行對回調(diào)函數(shù)隊(duì)列的調(diào)用。
3.2.2 應(yīng)用####
這個(gè)工具類應(yīng)用在Spring4.1的異步新特性中岸霹。Spring4.1提供了@Asyc注解疾层,被注解的類或方法將擁有異步處理能力
- 相關(guān)的配置:
<task:annotation-driven />指定@Async使用的線程池
<task:executor />配置線程池參數(shù)
3.3 各種工具類##
ClassUtils:Class類工具,提供操作class類的方法贡避。
比如:獲知類痛黎、方法上是否有注解,獲取類注解刮吧,獲取某package下所有class等湖饱。提供class緩存
CollectionUtils:集合工具類,提供集合的轉(zhuǎn)換、查找皇筛、判空等方法琉历。
DigestUtils:對java.serurity.MessageDigest的封裝坠七,提供單向加密方法水醋。
ReflectionUtils:反射工具類,提供各種反射操作彪置,并包裝了反射過程中可能出現(xiàn)的異常拄踪。
SystemPropertyUtils:placeholder解析工具類。