日志框架系列講解文章
日志框架 - 基于spring-boot - 使用入門
日志框架 - 基于spring-boot - 設(shè)計(jì)
日志框架 - 基于spring-boot - 實(shí)現(xiàn)1 - 配置文件
日志框架 - 基于spring-boot - 實(shí)現(xiàn)2 - 消息定義及消息日志打印
日志框架 - 基于spring-boot - 實(shí)現(xiàn)3 - 關(guān)鍵字與三種消息解析器
日志框架 - 基于spring-boot - 實(shí)現(xiàn)4 - HTTP請(qǐng)求攔截
日志框架 - 基于spring-boot - 實(shí)現(xiàn)5 - 線程切換
日志框架 - 基于spring-boot - 實(shí)現(xiàn)6 - 自動(dòng)裝配
上一篇我們講了框架實(shí)現(xiàn)的第五部分:如何在線程切換時(shí)保留上下文信息仅孩。
本篇主要講框架實(shí)現(xiàn)的第六部分:自動(dòng)裝配
自動(dòng)裝配(AutoConfiguration)是 Spring Boot 框架提供的核心功能纽谒。本篇中我們主要使用自動(dòng)裝配實(shí)現(xiàn)將之前第一部分到第五部分實(shí)現(xiàn)的功能組裝到一起弯囊。實(shí)現(xiàn)對(duì)業(yè)務(wù)代碼編程人員無(wú)感知泊交。具體實(shí)現(xiàn)如下。
/**
* 日志組件自動(dòng)裝配
*/
@Configuration
@ConditionalOnProperty(
value = "xpay.framework.logging.enabled",
havingValue = "true",
matchIfMissing = true)
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
public class LoggingAutoConfiguration {
@Value("${xpay.framework.executor.max-pool-size:16}")
int maxPoolSize;
/**
* 自定義線程池
* <p>
* 用于線程切換時(shí)的MDC延續(xù)
*/
@Bean
public TaskExecutor taskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(maxPoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setTaskDecorator(new MDCTaskDecorator());
executor.setThreadNamePrefix("MDCAdaptTaskExcutor-");
executor.initialize();
return executor;
}
@Bean
public MessageToLogAspect messageToLogAspect() {
return new MessageToLogAspect();
}
@Bean
public DefaultKeywords defaultKeywords() {
return new DefaultKeywords();
}
@Bean
public MDCSpringMvcHandlerInterceptor mdcSpringMvcHandlerInterceptor() {
return new MDCSpringMvcHandlerInterceptor();
}
/**
* Filter與Interceptor裝配
*/
@Configuration
protected static class LoggingWebConfiguration extends
WebMvcConfigurerAdapter {
@Autowired
MDCSpringMvcHandlerInterceptor mdcSpringMvcHandlerInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(mdcSpringMvcHandlerInterceptor);
}
}
/**
* Keywords裝配
*/
@Configuration
@ConditionalOnExpression(
"'${xpay.framework.logging.keywords}' matches '^([^,]+,)+.*$'")
protected static class MessageResolveAutoConfiguration {
@Value("${xpay.framework.logging.keywords}")
String keywordsPropertyString;
@Bean
public List<Keyword> keywordList() {
String[] keywordsProStringSplits =
keywordsPropertyString.split(",");
return Stream.of(keywordsProStringSplits)
.map(Keyword::new)
.collect(Collectors.toList());
}
@Bean
@Order(3)
public JsonMessageResolver jsonMessageResolver(
List<Keyword> keywordList) {
return new JsonMessageResolver(keywordList);
}
@Bean
@Order(2)
public XmlMessageResolver xmlMessageResolver(
List<Keyword> keywordList) {
return new XmlMessageResolver(keywordList);
}
@Bean
@Order(1)
public KeyValueMessageResolver keyValueMessageResolver(
List<Keyword> keywordList) {
return new KeyValueMessageResolver(keywordList);
}
@Bean
@Scope(scopeName = SCOPE_PROTOTYPE,
proxyMode = ScopedProxyMode.TARGET_CLASS)
public MessageResolverChain messageResolverChain(
List<MessageResolver> resolvers) {
return new MessageResolverChainImpl(resolvers);
}
@Bean
public RequestReplaceServletFilter requestReplaceServletFilter() {
return new RequestReplaceServletFilter();
}
@Bean
public FilterRegistrationBean requestReplaceFilter
(RequestReplaceServletFilter requestReplaceFilter) {
FilterRegistrationBean filterRegistrationBean = new
FilterRegistrationBean(requestReplaceFilter);
filterRegistrationBean.setDispatcherTypes(ASYNC, REQUEST);
// filterRegistrationBean.setOrder(Ordered.HIGHEST_PRECEDENCE + 5);
return filterRegistrationBean;
}
}
}
至此,日志框架所有實(shí)現(xiàn)都已介紹了。有想法的小伙伴也可以在此基礎(chǔ)上進(jìn)行改進(jìn)词身。實(shí)現(xiàn)想要的功能。