Spring-Boot 使用手记
Service 注解
如果使用 Service
注解,请务必使用 ComponentScan
并指定扫描路径。
定时器支持
如果要使用定时器,请务必使用 EnableScheduling
开启定时器支持,并且 spring-boot 默认的定时器是单线程模式的,请添加如下代码:
/**
* 定时器的多线程支持
*/
@Configuration
public class ScheduleConfig implements SchedulingConfigurer {
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
// @EnableScheduling 和 @Scheduled默认是基于单线程
taskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
}
}
异步支持
如果要使用 Async
支持异步调用,请务必使用 EnableAsync
开启异步支持,且需要手动实现异步的线程池支持。
/**
* 异步执行的多线程支持
*/
@Configuration
public class AsyncConfig {
@Bean
public Executor taskExecutor() {
return new SimpleAsyncTaskExecutor();
}
}
redis 支持
新版本的 spring-boot 使用的 redis 支持,在 pom 中添加如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
SpringUtils
获取程序的 context,最好加上 Lazy(false)
的注解
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
// don't move this class package path
@Component
@Lazy(false)
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext = null;
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if (SpringUtils.applicationContext == null) {
SpringUtils.applicationContext = applicationContext;
}
}
public static Object getBean(String name) {
return getApplicationContext().getBean(name);
}
// 通过class获取Bean.
public static <T> T getBean(Class<T> clazz) {
return getApplicationContext().getBean(clazz);
}
// 通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) {
return getApplicationContext().getBean(name, clazz);
}
}
spring-boot 缓存
很多时候,使用 redis 作为缓存是为了减少数据库读写,以及为了在集群中获取和数据库类似的同一性。但是有时候,低延迟的同一性不是那么重要,就不会考虑引入 redis 等 NoSql 服务。
这时候就可以用 Cacheable
注解了。如下:
@Configuration
@EnableCaching
public class BeanConfig {
@Bean
public CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
return cacheManager;
}
}
ConcurrentMapCacheManager
是一个最为简单的缓存管理器,但是没有设置过期时间的接口。此时,可以使用 Caffeine Cache
,作为缓存管理器。
@SpringBootApplication
@EnableScheduling
@EnableCaching
public class BeanConfig {
@Bean
@Primary
public CacheManager caffeineCacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
ArrayList<CaffeineCache> caches = Lists.newArrayList();
caches.add(new CaffeineCache("defaultCache",
Caffeine.newBuilder().recordStats()
.expireAfterWrite(300, TimeUnit.SECONDS)
.maximumSize(1000)
.build())
);
cacheManager.setCaches(caches);
return cacheManager;
}
}
spring-boot中配置和使用Caffeine Cache
参考文档