@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) @Documented public @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; @Configuration public 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; @Slf4j public 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 @AllArgsConstructor public 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 @AllArgsConstructor public 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如何实现配置化日志输出”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注创新互联网站,小编会继续努力为大家带来更多实用的文章!
网站名称:@EnableAsync如何实现配置化日志输出
当前网址:http://scyanting.com/article/jhhsep.html