动态切面

简介: `AdviceConfiguration` 类用于动态注册一个基于 AspectJ 的切面顾问,该顾问通过 `@ConditionalOnExpression` 注解控制是否生效。配置中包含一个从 Apollo 获取的 JSON 值,用于构建方法拦截器的切入点表达式,涉及特定包和类。拦截器 `ControllerAdvice` 实现了 `MethodInterceptor`,用于记录请求日志,包括 URL、参数和执行时间,同时根据配置决定是否对返回结果进行加密。
package integration.configuration;

import cn.hutool.core.collection.CollUtil;
import com.ctrip.framework.apollo.spring.annotation.ApolloJsonValue;
import integration.advice.ControllerAdvice;
import org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 动态注入需要切面的类
 * 没什么卵用
 */
@Configuration
public class AdviceConfiguration {

    private String expression;

    [
        {
            "package": "com.xx.xx.xxxxxx.xxxxxxx.controller",
            "class": [
                "XXXXXXXController",
                "XXXXXXXXController"
            ]
        }
    ]
    
    @ApolloJsonValue("${advice.expression:}")
    private void setExpression(List<Map<String, Object>> value) {
        if (CollUtil.isEmpty(value)) return;
        StringBuilder sb = new StringBuilder();
        for (Map<String, Object> item : value) {
            List<String> clazz = (List<String>) item.get("class");
            for (String s : clazz) {
                sb.append("execution(* ");
                sb.append(item.get("package")).append(".");
                sb.append(s);
                sb.append(".*(..)) || ");
            }
        }
        expression = sb.substring(0, sb.length() - 4);
    }

    private final Map<String, Boolean> aa = new HashMap<>();

    @Bean
    @ConditionalOnExpression("${advice.switch:false}")
    public AspectJExpressionPointcutAdvisor config() {
        AspectJExpressionPointcutAdvisor advisor = new AspectJExpressionPointcutAdvisor();
        advisor.setExpression(expression);
        advisor.setAdvice(new ControllerAdvice());
        return advisor;
    }

}

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import integration.util.LoginUtil;
import lombok.extern.slf4j.Slf4j;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
/**
* 这俩配合着用
*/
public class ControllerAdvice implements MethodInterceptor {
    
    @Value("${isPrd:false}")
    private boolean isEncryption;

    private final ObjectMapper objectMapper = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
            .configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        long start = System.currentTimeMillis();
        String requestUrl = getRequestUrl();
        Map<String, String> headers = LoginUtil.getHeaders();
        Object[] args = invocation.getArguments();
        log.info("Controller.LogAspect url:{} headers:{}, param:{} ", requestUrl, headers, printObj(args));
        Object result = invocation.proceed();
        log.info("Controller.LogAspect url:{} cost:{}ms result:{} ", requestUrl, System.currentTimeMillis() - start, printObj(result));
        return result;
    }

    private String getRequestUrl(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return attributes == null ? "" : attributes.getRequest().getRequestURI();
    }

    private Object printObj(Object o){
        try {
            return isEncryption ? Base64.getEncoder().encodeToString(objectMapper.writeValueAsBytes(o)) : o;
        } catch (JsonProcessingException e) {
            return e.getMessage();
        }
    }
}
相关文章
|
存储 监控 Shell
【Shell 命令集合 磁盘管理 】Linux 管理磁盘配额 quota命令使用教程
【Shell 命令集合 磁盘管理 】Linux 管理磁盘配额 quota命令使用教程
362 0
|
算法 安全 网络安全
简单认识一下mbedTLS
简单认识一下mbedTLS
1938 0
|
网络协议 Unix Linux
计算机网络 套接字函数 | socket、bind、listen、accept、connect
计算机网络 套接字函数 | socket、bind、listen、accept、connect
290 0
|
存储 算法 数据安全/隐私保护
【密码学】一文读懂白盒AES(Chow方案)(一)
本文主要参考了文献^[1], 代码参考了^[2], 这里感谢文献作者和代码作者,如果有能力的大佬,可以自行查看原文献,个人水平有限,有哪里写的不对的地方,也欢迎读者指正。
4757 0
【密码学】一文读懂白盒AES(Chow方案)(一)
|
8月前
|
安全 网络安全 Apache
如何为服务器生成一个TLS证书
通过以上步骤,您可以成功地为服务器生成并配置TLS证书,确保网站的安全性。本文涵盖了从生成私钥、创建CSR、使用自签名证书到获取正式证书的详细步骤,并且对每个步骤进行了详细的解释,使即使是非专业人士也能顺利完成TLS证书的配置。
919 79
|
区块链
【智能合约】新版Remix编写实现第一个HelloWorld
【智能合约】新版Remix编写实现第一个HelloWorld
294 2
|
Java API 开发者
探索Java中的Lambda表达式
本文将深入探讨Java 8中引入的Lambda表达式,这一特性如何简化了代码编写和提高了程序的可读性。我们将从Lambda表达式的基础概念出发,逐步过渡到实际应用案例,并分析其对Java函数式编程范式的影响。
81 27
|
机器学习/深度学习 数据采集 人工智能
使用机器学习进行用户行为预测的技术探索
【8月更文挑战第9天】使用机器学习进行用户行为预测是一项复杂而充满挑战的任务。它要求开发者具备扎实的机器学习基础、丰富的数据处理经验和深入的业务理解。通过不断的数据收集、处理、特征工程、模型训练和优化,可以构建出高效、准确的用户行为预测模型,为企业决策提供有力支持。未来,随着技术的不断发展和数据的不断积累,用户行为预测领域将迎来更加广阔的发展前景。
|
SQL 数据挖掘
SQLBolt,一个练习SQL的宝藏网站
SQLBolt,一个练习SQL的宝藏网站
333 0
|
JavaScript Java 测试技术
基于SpringBoot+Vue+uniapp微信小程序的大学生智能消费记账系统的详细设计和实现
基于SpringBoot+Vue+uniapp微信小程序的大学生智能消费记账系统的详细设计和实现
276 1