這篇文章主要介紹“@EnableAsync如何實現(xiàn)配置化日志輸出”,在日常操作中,相信很多人在@EnableAsync如何實現(xiàn)配置化日志輸出問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”@EnableAsync如何實現(xiàn)配置化日志輸出”的疑惑有所幫助!接下來,請跟著小編一起來學(xué)習(xí)吧!
公司主營業(yè)務(wù):網(wǎng)站建設(shè)、網(wǎng)站設(shè)計、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。成都創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。成都創(chuàng)新互聯(lián)公司推出寧津免費做網(wǎng)站回饋大家。
聲明啟動類注解、需要import的配置類。 常規(guī)情況會額外指定一下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 關(guān)系。
adivce -> LogInterceptor: 切面執(zhí)行處理
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 ListbasePackages; 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 Mapargs; }
到此,關(guān)于“@EnableAsync如何實現(xiàn)配置化日志輸出”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識,請繼續(xù)關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>
新聞名稱:@EnableAsync如何實現(xiàn)配置化日志輸出
文章源于:http://weahome.cn/article/jhhsep.html