@EnableAsync如何实现配置化日志输出
发表于:2025-02-04 作者:千家信息网编辑
千家信息网最后更新 2025年02月04日,这篇文章主要介绍"@EnableAsync如何实现配置化日志输出",在日常操作中,相信很多人在@EnableAsync如何实现配置化日志输出问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法
千家信息网最后更新 2025年02月04日@EnableAsync如何实现配置化日志输出
这篇文章主要介绍"@EnableAsync如何实现配置化日志输出",在日常操作中,相信很多人在@EnableAsync如何实现配置化日志输出问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答"@EnableAsync如何实现配置化日志输出"的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
声明启动类注解、需要import的配置类。 常规情况会额外指定一下Ordered、proxyTargetClass,本例从简
import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;import org.springframework.context.annotation.Import;@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Import(LogConfigurationImport.class)@Documentedpublic @interface EnableLog { /** * 指定包路径 */ String[] basePackages() default {};}
配置类中需要
advise-> LogPointcutAdvisor : 绑定pointcut与adivce 关系。
adivce -> LogInterceptor: 切面执行处理import javax.annotation.Resource;import org.springframework.aop.PointcutAdvisor;import org.springframework.context.EnvironmentAware;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.ImportAware;import org.springframework.core.Ordered;import org.springframework.core.annotation.AnnotationAttributes;import org.springframework.core.env.Environment;import org.springframework.core.task.TaskExecutor;import org.springframework.core.type.AnnotationMetadata;import org.springframework.lang.Nullable;import lombok.Setter;@Configurationpublic class LogConfigurationImport implements ImportAware, EnvironmentAware { @Nullable protected AnnotationAttributes enableLogAttributes; @Setter private Environment environment; @Resource TaskExecutor taskExecutor; @Override public void setImportMetadata(AnnotationMetadata importMetadata) { this.enableLogAttributes = AnnotationAttributes .fromMap(importMetadata.getAnnotationAttributes(EnableLog.class.getName(), false)); if (this.enableLogAttributes == null) { throw new IllegalArgumentException( "@EnableLog is not present on importing class " + importMetadata.getClassName()); } } @Bean public LogInterceptor logInterceptor(TaskExecutor taskExecutor) { return new LogInterceptor(handler(environment), taskExecutor); } @Bean public ILogHandler handler(Environment environment) { return new LocalLogHandler(environment); } @Bean public PointcutAdvisor pointcutAdvisor(LogInterceptor logInterceptor) { LogPointcutAdvisor advisor = new LogPointcutAdvisor(this.enableLogAttributes.getStringArray("basePackages")); advisor.setAdvice(logInterceptor); if (enableLogAttributes != null) { advisor.setOrder(Ordered.LOWEST_PRECEDENCE - 1); } return advisor; }}----import java.util.Arrays;import java.util.List;import java.util.concurrent.ConcurrentHashMap;import org.springframework.aop.ClassFilter;import org.springframework.aop.Pointcut;import org.springframework.aop.support.AbstractBeanFactoryPointcutAdvisor;import org.springframework.aop.support.ComposablePointcut;import org.springframework.aop.support.annotation.AnnotationMatchingPointcut;import org.springframework.stereotype.Controller;import org.springframework.util.CollectionUtils;import org.springframework.web.bind.annotation.RequestMapping;import lombok.AllArgsConstructor;import lombok.extern.slf4j.Slf4j;@Slf4jpublic class LogPointcutAdvisor extends AbstractBeanFactoryPointcutAdvisor { private static final long serialVersionUID = 1L; private ComposablePointcut pointcut; //组合方式的pointcut public LogPointcutAdvisor(String[] basePackages) { // 确定切面范围 pointcut = new ComposablePointcut(new AnnotationMatchingPointcut(Controller.class, RequestMapping.class, true)); if (basePackages != null && basePackages.length > 0) { pointcut.intersection(new LogPackageFilter(Arrays.asList(basePackages))); } } @AllArgsConstructor static class LogPackageFilter implements ClassFilter { private List
basePackages; private final ConcurrentHashMap classMatchMap = new ConcurrentHashMap<>(50); @Override public boolean matches(Class> clazz) { String name = clazz.getName(); boolean match = classMatchMap.computeIfAbsent(name, key -> !CollectionUtils.isEmpty(basePackages) && basePackages.stream().anyMatch(t -> key.startsWith(t))); log.debug("name: {} LogPackageFilter -> {}", name, match); return match; } } @Override public Pointcut getPointcut() { return this.pointcut; }}----import java.lang.reflect.Method;import java.lang.reflect.Parameter;import java.util.Map;import java.util.concurrent.ConcurrentHashMap;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.apache.commons.lang.ArrayUtils;import org.apache.commons.lang3.StringUtils;import org.springframework.aop.framework.AopProxyUtils;import org.springframework.core.BridgeMethodResolver;import org.springframework.core.MethodClassKey;import org.springframework.core.task.TaskExecutor;import org.springframework.lang.Nullable;import org.springframework.web.bind.annotation.RequestMapping;import com.google.common.collect.Maps;public class LogInterceptor implements MethodInterceptor { private final Map 实际的日志操作处理类
/** * * 日志操作 */public interface ILogHandler { String getAppName(); void handle(LogInfo logInfo);}import org.springframework.core.env.Environment;import com.yy.cs.base.json.Json;import lombok.AllArgsConstructor;import lombok.extern.slf4j.Slf4j;/** * * 本地日志输出 */@Slf4j@AllArgsConstructorpublic class LocalLogHandler implements ILogHandler { Environment environment; @Override public String getAppName() { return environment.getProperty("spring.application.name"); } @Override public void handle(LogInfo logInfo) { log.info("request log: {}", Json.ObjToStr(logInfo)); }}----import java.util.Map;import lombok.AllArgsConstructor;import lombok.Data;import lombok.NoArgsConstructor;@Data@NoArgsConstructor@AllArgsConstructorpublic class LogInfo { private String requestUrl; private String method; private String clas; private long start; private long cost; private String errorMsg; private String exceptionType; private Map
args;}
到此,关于"@EnableAsync如何实现配置化日志输出"的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注网站,小编会继续努力为大家带来更多实用的文章!
日志
配置
输出
学习
切面
方法
更多
处理
帮助
实用
接下来
实际
对象
常规
情况
文章
方式
注解
理论
知识
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库直接备份
中华人民共和国网络安全审查办法
广东系统软件开发怎么样
安全牛数据库安全
软件开发属于那一大类
网络安全法宣传册样本
物流软件开发行业市场情况
网络安全学历要求低
网络安全事件感悟
宿迁登奥网络技术有限公司
无服务器有什么风险
大连海事数据库原理
用友软件都需要下载数据库吗
疫情利好网络安全
重庆高校在线云数据库
福建质量网络技术咨询产品
软件开发干到多少岁
esi数据库的使用步骤吗
锋云服务器换硬盘
数据库计算字段不可排序
手机数据库怎么打开
服务器安装管理维护的软件
新罗区丹路圣网络技术工作室
数据库取值唯一的约束
漯河网络安全工程师证
厚得网络技术工作室
学生机房网络安全管理制度
套利软件开发者
代理服务器构建
服务器要钱吗