Integration
Message Conversion
WebMvcConfigurationSupport 内含默认的 Converter
BufferedImageHttpMessageConverter 返回图片
1 |
|
6. Mail
Spring Boot 的使用方式:
(1) 配置并将 JavaMailSender 注入到 IOC 容器,类似一个 Mail 工厂配置,可以 getSession,也可以 createMimeMessage
1 |
|
(2) 使用 javaMailSender 发送。MimeMessageHelper 类似 Builder 设计,但是没有做链式调用。
1 | MimeMessage mimeMessage = javaMailSender.createMimeMessage(); |
7. Task Execution and Scheduling
Spring Framework 分别使用 TaskExecutor 和 TaskScheduler 接口为异步执行和任务调度提供了抽象。Spring 还具有那些支持线程池的接口实现或在应用程序服务器环境中委托 CommonJ。最终,通用接口之间的这些实现的使用抽象出了 Java SE5,Java SE 6 以及 Java EE 环境的差异。
Spring 还具有支持使用 Timer 调度的集成类,以及 Quartz Scheduler。你可以通过使用 FactoryBean,可选的分别对 Timer 或者 Trigger 实例的引用设置这两个调度器。此外,用于 Quartz 调度器和 Timer 的便利类是可用的,它让你调用现存的目标对象的方法(类似于普通的 MethodInvokingFactoryBean 操作)。
7.1. The Spring TaskExecutor Abstraction
Executor 是 JDK 用于线程池概念的名称。之所以叫 “executor” 是因为实际上不能保证底层的实现就是池。一个 executor 可以是单线程,甚至是同步的。Spring 的抽象隐藏了 Java SE 和 Java EE 环境之间的实现细节。
Spring 的 TaskExecutor 接口与 java.util.concurrent.Executor 接口相同。实际上,最初其主要存在的原因就是在使用线程池的时候抽象出对 Java 5 的需求。该接口只有一个方法(execute(Runnable task)),该方法接受给予线程池的语义和配置的任务。
7.1.1. TaskExecutor Types
Spring 包含了许多预置的 TaskExecutor 实现。很有可能,你永远不需要实现自己的类。Spring 提供的变体如下:
SyncTaskExecutor: 此实现不会异步运行调用。相反,每个调用都发生在调用线程中。它主要用于不需要多线程的情况,例如在简单的测试用例中。ThreadPoolTaskExecutor: 此实现最常用。它暴露了用于配置java.util.concurrent.ThreadPoolExecutor的 Bean 属性,并将其包装在TaskExecutor中。如果你需要适应其他类型的java.util.concurrent.Executor,我们建议你改用ConcurrentTaskExecutor。
7.1.2. Using a TaskExecutor
Spring 的 TaskExecutor 实现被用作简单的 Java Bean。在下面的示例中,我们定义了一个使用 ThreadPoolTaskExecutor 的 Bean,异步地打印一组消息:
1 | import org.springframework.core.task.TaskExecutor; |
如你所见,你没有从池中检索线程并自己执行,而是将你的 Runnable 添加到队列中。然后 TaskExecutor 使用其内部规则来决定任务何时运行。
为了配置 TaskExecutor 使用的规则,我们将公开简单的 Bean 属性:
1 | <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> |
7.2. The Spring TaskScheduler Abstraction
除了 TaskExecutor 抽象外,
8. Cache Abstraction
8.1. Understanding the Cache Abstraction
Buffer 和 Cache
一般地,buffer 可以翻译为缓冲区,用于高速与低速的实体之间的中间存储,缓冲区至少对知晓它的一方是可见的。
cache 可以翻译为缓存,根据定义是隐藏的,任何一方都不知晓。
Spring 提供了一些缓存抽象的实现:
- SimpleCacheConfiguration
- EhCacheCacheConfiguration
- GenericCacheConfiguration
- RedisCacheConfiguration
- …
SpringBoot CacheAutoConfiguration 中使用 @Import 导入了 CacheConfigurationImportSelector.class,其中导入了枚举类 CacheType 中所有的缓存类型。
SimpleCacheConfiguration
底层使用 concurrentMap 实现,见 SimpleCacheConfiguration 注入 ConcurrentMapCacheManager。ConcurrentMapCacheManager 属性 dynamic 可以配置 cacheName 是否可以动态生成,默认为 true。
8.2. Declarative Annotation-based Caching
Spring 缓存抽象提供了一组 Java 注解:
@Cacheable:触发缓存填充@CacheEvict:触发缓存驱逐@CachePut:在不干扰方法执行的情况下更新缓存@Caching:重新组合要应用于方法的多个缓存操作@CacheConfig:在类级别共享一些常见的缓存相关设置
8.2.1. The @Cacheable Annotation
| 注解属性 | 说明 |
|---|---|
| value / cacheNames | 缓存的名字 |
| key | 缓存数据使用的 key,默认使用方法参数 |
| keyGenerator | 自定义 key 生成器,实现 KeyGenerator |
| cacheManager | 指定缓存管理器 |
| condition | 指定符合条件的情况下才缓存 |
| unless | 缓存的否定条件 |
| sync | 是否使用异步模式 |
Default Key Generation
key 默认采用 SimpleKeyGenerator 生成。以方法参数为标识。
Synchronized Caching
Spring Core 框架的 CacheManager 实现都支持 sync。其他缓存库未必。
Available Caching SpEL Evaluation Context
Cache SpEL 可用元数据,具体见官方表。
8.2.2. The @CachePut Annotation
每次都调用方法,缓存结果。
8.2.3. The @CacheEvict annotation
清空缓存
8.2.6. Enabling Caching Annotations
1 |
|
8.3. JCache (JSR-107) Annotations
从 Spring 4.1 开始,Spring 缓存抽象完全支持 JCache 注解
8.3.1. Feature Summary
| Spring | JSR-107 | 备注 |
|---|---|---|
| @Cacheable | @CacheResult | |
| @CachePut | @CachePut | |
| @CacheEvict | @CacheRemove | |
| @CacheEvict(allEntries=true) | @CacheRemoveAll | |
| @CacheConfig | @CacheDefaults |
JCache 的 CacheResolver 概念上与 Spring CacheResolver 接口相同,只是 JCache 仅支持单个 Cache。默认,Simple 实现会根据注解上的名称检索要使用的 Cache,如果注解上没有指定名称,则会自动生成一个默认值。
8.3.2. Enabling JSR-107 Support
如果类路径同时存在 JSR-107 API 和 spring-context-support,@EnableCaching 和 cache:annotation-driven 都会自启用 JCache。
若你觉得我的文章对你有帮助,欢迎点击上方按钮对我打赏
扫描二维码,分享此文章