概述
org.springframework.context.ApplicationContext接口是Spring IoC的容器,负责bean的初始化,配置和装配。ApplicationContext通过读取元数据(configuration metadata)获取该把bean注入到哪个对象。元数据可以是XML, Java注解或Java代码。
Spring提供了几种ApplicationContext的实现。本地化项目使用的ClassPathXMLApplicationContext或FileSystemXMLApplicationContext. 然而XML是比较传统的配置方式,使用注解或代码配合少量XML作为元数据可以使配置更精简。
在大多数应用场景,我们不需要自己去创建ApplicationContext的实例。例如在web应用中,只需要在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
元数据的三种配置方式:
- 完全XML
- 少量XML(component-scan) + Java注解
- Java代码(全部使用注解)
1 spring-core 包结构
<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生成的动态代理类命名规则(className$$classNameBySpringCGLIB$$hashCode)
3.core
4.lang 条件编译注解
5.objenesis 对象实例化工具,封装后提供缓存功能(单例)
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
转码工具
2.4 env##
2.4.1 概述####
env包是Spring3.1开始提供的新的属性管理API,提供配置读取和环境划分能力,主要接口:PropertySource和Environment
2.4.2 PropertySource####
PropertySource:属性源,key-value属性对抽象,比如用于配置数据
PropertyResolver:属性解析器,用于解析相应key的value
2.4.2.1主要实现类#####
MapPropertySource:属性来自于一个Map
ResourcePropertySource:属性来自于一个properties文件
ServletContextPropertySource:属性来自ServletContext上下文初始化参数
CompositePropertySource:提供了组合PropertySource的功能,查找顺序就是注册顺序。
2.4.3 Environment####
Environment:环境,本身是一个PropertyResolver,但是提供了Profile特性,即可以根据环境得到相应数据(即激活不同的Profile,可以得到不同的属性数据,比如用于多环境场景的配置(正式机、测试机、开发机DataSource配置))
Profile:剖面,Environment使Spring具有了剖面特性,只有激活的剖面的组件/配置才会注册到Spring容器,类似于maven中profile。这是context包中的一个注解。另外context包中还有一个叫做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 概述####
在日常程序开发中,处理外部资源是很繁琐的事情,我们可能需要处理URL资源、File资源资源、ClassPath相关资源、服务器相关资源(JBoss AS 5.x上的VFS资源)等等很多资源。因此处理这些资源需要使用不同的接口,这就增加了我们系统的复杂性;而且处理这些资源步骤都是类似的(打开资源、读取资源、关闭资源),因此如果能抽象出一个统一的接口来对这些底层资源进行统一访问,是不是很方便,而且使我们系统更加简洁,都是对不同的底层资源使用同一个接口进行访问。
spring提供一个Resource接口来统一这些底层资源一致的访问,而且提供了一些便利的接口,从而能提供我们的生产力。
2.5.2 Resource接口####
Spring的Resource接口代表底层外部资源,对JDK InputStream的扩展,提供了对底层外部资源的一致性访问接口。
2.5.3 主要实现类####
2.5.3.1 ByteArrayResource#####
ByteArrayResource代表byte[]数组资源,对于“getInputStream”操作将返回一个ByteArrayInputStream。ByteArrayResource可多次读取数组资源,即isOpen ()永远返回false。
2.5.3.2 InputStreamResource#####
InputStreamResource代表java.io.InputStream字节流,对于“getInputStream ”操作将直接返回该字节流,因此只能读取一次该字节流,即“isOpen”永远返回true。
2.5.3.4 FileSystemResource
FileSystemResource代表java.io.File资源,对于“getInputStream ”操作将返回底层文件的字节流,“isOpen”将永远返回false,从而表示可多次读取底层文件的字节流。
2.5.3.5 ClassPathResource
ClassPathResource代表classpath路径的资源,将使用ClassLoader进行加载资源。classpath 资源存在于类路径中的文件系统中或jar包里,且“isOpen”永远返回false,表示可多次读取资源。
ClassPathResource加载资源替代了Class类和ClassLoader类的“getResource(String name)”和“getResourceAsStream(String name)”两个加载类路径资源方法,提供一致的访问方式。
ClassPathResource提供了三个构造器:
public ClassPathResource(String path):使用默认的ClassLoader加载“path”类路径资源;
public ClassPathResource(String path, ClassLoader classLoader):使用指定的ClassLoader加载“path”类路径资源;
比如当前类路径是“cn.javass.spring.chapter4.ResourceTest”,而需要加载的资源路径是“cn/javass/spring/chapter4/test1.properties”,则将加载的资源在“cn/javass/spring/chapter4/test1.properties”;
public ClassPathResource(String path, Class<?> clazz):使用指定的类加载“path”类路径资源,将加载相对于当前类的路径的资源;
2.5.3.6 UrlResource#####
UrlResource代表URL资源,用于简化URL资源访问。“isOpen”永远返回false,表示可多次读取资源。
UrlResource一般支持如下资源访问:
http:通过标准的http协议访问web资源,如new UrlResource(“http://地址”);
ftp:通过ftp协议访问资源,如new UrlResource(“ftp://地址”);
file:通过file协议访问本地文件系统资源,如new UrlResource(“file:d:/test.txt”);
2.5.3.7 ServletContextResource#####
ServletContextResource代表web应用资源,用于简化servlet容器的ServletContext接口的getResource操作和getResourceAsStream操作;
2.5.4 ResourceLoader接口####
public interface ResourceLoader {
Resource getResource(String location);
ClassLoader getClassLoader();
}
getResource接口用于根据提供的location参数返回相应的Resource对象;而getClassLoader则返回加载这些Resource的ClassLoader。
Spring提供了一个适用于所有环境的DefaultResourceLoader实现,可以返回ClassPathResource、UrlResource;还提供一个用于web环境的ServletContextResourceLoader,它继承了DefaultResourceLoader的所有功能,又额外提供了获取ServletContextResource的支持。
ResourceLoader在进行加载资源时需要使用前缀来指定需要加载:“classpath:path”表示返回ClasspathResource,“http://path”和“file:path”表示返回UrlResource资源,如果不加前缀则需要根据当前上下文来决定,DefaultResourceLoader默认实现可以加载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配置形式自定义它们暴露的各个属性。
TaskExecutor接口,是对java.util.concurrent.Executor接口的扩展。给其他组件提供线程池的抽象。
例如ApplicationEventMulticaster组件、JMS的AbstractMessageListenerContainer和对Quartz的整合都使用了TaskExecutor抽象来提供线程池。
2.8.2 配置与使用####
<bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
<!-- 核心线程数 -->
<property name="corePoolSize" value="5" />
<!-- 最大线程数 -->
<property name="maxPoolSize" value="50" />
<!-- 队列最大长度 -->
<property name="queueCapacity" value="1000" />
<!-- 线程池维护线程所允许的空闲时间,默认为60s -->
<property name="keepAliveSeconds" value="60" />
</bean>
@Resource(name = "taskExecutor")
private TaskExecutor taskExecutor;
taskExecutor.execute(()-> {
...
});
2.8.3 实现类
从类图上很明显可以看出分为同步Executor和异步Executor。同步比较简单,就是调用一下的run方法。下面主要分析异步。
- SimpleAsyncTaskExecutor:每次调用都启动一个新线程。但是,它还是支持对并发总数设限,当超过线程并发总数限制时,阻塞新的调用,直到有位置被释放。
- ConcurrentTaskExecutor:对Java 5 java.util.concurrent.Executor类的适配,暴露了Executor的配置参数作为bean属性,可以配置自己的Executor,可以设置任务装饰器。
- **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秒执行一次
public void foo(){
...
}
3.Spring-Core.utils#
<pre>
util
├─backoff
├─comparator
├─concurrent
└─xml
</pre>
3.1 backoff##
Spring封装的退避算法,用于获取重试间隔。两个实现类,FixedBackOff是按照固定时间间隔重试,ExponentialBackOff是间隔以指数方式增长。
3.2 concurrent##
Spring中对java.util.concurrent.Future的扩展,支持Future适配,FutureTask添加多个回调函数。
3.2.1 主要类
ListenableFuture<T>:增加扩展功能使用addCallback()方法支持增加回调函数
ListenableFutureTask<T>:FutureTask子类,主要是为了增加回调函数注册和回调函数调用功能。该类重写了done()方法,执行对回调函数队列的调用。
3.2.2 应用####
这个工具类应用在Spring4.1的异步新特性中。Spring4.1提供了@Asyc注解,被注解的类或方法将拥有异步处理能力
- 相关的配置:
<task:annotation-driven />指定@Async使用的线程池
<task:executor />配置线程池参数
3.3 各种工具类##
ClassUtils:Class类工具,提供操作class类的方法。
比如:获知类、方法上是否有注解,获取类注解,获取某package下所有class等。提供class缓存
CollectionUtils:集合工具类,提供集合的转换、查找、判空等方法。
DigestUtils:对java.serurity.MessageDigest的封装,提供单向加密方法。
ReflectionUtils:反射工具类,提供各种反射操作,并包装了反射过程中可能出现的异常。
SystemPropertyUtils:placeholder解析工具类。