亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

@EnableAsync如何實現配置化日志輸出

發布時間:2021-07-05 18:37:31 來源:億速云 閱讀:162 作者:chen 欄目:大數據

這篇文章主要介紹“@EnableAsync如何實現配置化日志輸出”,在日常操作中,相信很多人在@EnableAsync如何實現配置化日志輸出問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”@EnableAsync如何實現配置化日志輸出”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

  1. 聲明啟動類注解、需要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 {};
    }


  2. 配置類中需要
     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<String> basePackages;
            private final ConcurrentHashMap<String, Boolean> 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<Object, String> uriCache = new ConcurrentHashMap<>(1024);
        private ILogHandler logHandler;
        private TaskExecutor taskExecutor;
    
        public LogInterceptor(ILogHandler logHandler, TaskExecutor taskExecutor) {
            this.logHandler = logHandler;
            this.taskExecutor = taskExecutor;
        }
    
        @Override
        public Object invoke(MethodInvocation invocation) throws Throwable {
            long start = System.currentTimeMillis();
            String exceptionMsg = null;
            String exceptionType = null;
            try {
                Object result = invocation.proceed();
                return result;
            } catch (Throwable e) {
                exceptionMsg = e.getMessage();
                exceptionType = e.getClass().getName();
                throw e;
            } finally {
                final String errorMsg = exceptionMsg;
                final String errorType = exceptionType;
                long end = System.currentTimeMillis();
                taskExecutor.execute(() -> {
                    handLog(invocation, start, end, errorMsg, errorType);
                });
            }
        }
    
        private void handLog(MethodInvocation invocation, long start, long end, final String errorMsg,
                final String errorType) {
            Map<String, Object> args = null;
            Method method = BridgeMethodResolver.findBridgedMethod(invocation.getMethod());
            Class<?> targetClass = getTargetClass(invocation.getThis());
            String reqUrl = getRequestUrl(method, targetClass);
            Parameter[] parameters = method.getParameters();
            Object[] arguments = invocation.getArguments();
            if (parameters != null && parameters.length > 1) {
                args = Maps.newHashMapWithExpectedSize(15);
                for (int i = 0; i < parameters.length; i++) {
                    args.put(parameters[i].getName(), i < arguments.length ? arguments[i] : null);
                }
            }
    
            logHandler.handle(new LogInfo(reqUrl, method.getName(), targetClass.getName(), start, end - start, errorMsg,
                    errorType, args));
        }
        //獲取對象真實的class類型
        private Class<?> getTargetClass(Object target) {
            return AopProxyUtils.ultimateTargetClass(target);
        }
    
        public String getRequestUrl(Method method, @Nullable Class<?> targetClass) {
            if (method.getDeclaringClass() == Object.class) {
                return null;
            }
    
            Object cacheKey = getCacheKey(method, targetClass);
            String requestUrl = this.uriCache.get(cacheKey);
            if (requestUrl == null) {
                requestUrl = retrieveUriFromHandlerMethod(method, targetClass);
                this.uriCache.put(cacheKey, requestUrl);
            }
            return requestUrl;
        }
        //通過方法獲取URL
        private String retrieveUriFromHandlerMethod(Method method, Class<?> targetClass) {
    
            RequestMapping classRequestMapping = targetClass.getAnnotation(RequestMapping.class);
    
            StringBuilder uriSb = new StringBuilder(256);
            if (classRequestMapping != null) {
                String[] value = classRequestMapping.value();
                if (ArrayUtils.isNotEmpty(value) && StringUtils.isNotBlank(value[0])) {
                    String classUri = trimFirstSlash(value[0]);
                    classUri = trimLastSlash(classUri);
                    uriSb.append(classUri);
                }
            }
    
            RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class);
            if (methodRequestMapping != null) {
                String[] value = methodRequestMapping.value();
                if (ArrayUtils.isNotEmpty(value) && StringUtils.isNotBlank(value[0])) {
                    boolean hasClassUri = uriSb.length() != 0;
                    String methodUri = trimFirstSlash(value[0]);
                    if (hasClassUri) {
                        uriSb.append("/");
                    }
                    uriSb.append(methodUri);
                }
            }
    
            return uriSb.toString().replaceAll("[{}]", "");
        }
    
        private String trimFirstSlash(String uri) {
            return uri.startsWith("/") ? uri.substring(1) : uri;
        }
    
        private String trimLastSlash(String uri) {
            return uri.lastIndexOf("/") == uri.length() - 1 ? uri.substring(0, uri.length() - 1) : uri;
    
        }
    
        private Object getCacheKey(Method method, Class<?> targetClass) {
            return new MethodClassKey(method, targetClass);
        }
    }


  3. 實際的日志操作處理類

    /**
     * 
     * 日志操作
     */
    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<String, Object> args;
    }


到此,關于“@EnableAsync如何實現配置化日志輸出”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

玉田县| 大荔县| 瑞安市| 同心县| 廉江市| 中牟县| 界首市| 射阳县| 虞城县| 侯马市| 三台县| 夹江县| 叶城县| 德庆县| 永靖县| 福清市| 华亭县| 长兴县| 玛曲县| 榆树市| 大英县| 馆陶县| 绍兴县| 渝中区| 岳西县| 云梦县| 琼中| 和政县| 桓仁| 松江区| 河津市| 南靖县| 巴彦淖尔市| 清水县| 嘉鱼县| 郓城县| 建平县| 白玉县| 淳安县| 巫山县| 潞城市|