SpringAop中的Advice通知实例

 更新时间:2023年09月25日 11:06:53   作者:至学者  
这篇文章主要介绍了SpringAop中的Advice通知详解,Spring的AOP功能中一个关键概念是通知Advice与切点Pointcut表达式相关联在特定节点织入一些逻辑,Spring提供了五种类型的通知,需要的朋友可以参考下

一 概述

  • @Before:前置通知
  • @After :后置通知,方法执行完之后
  • @AfterReturning:返回通知,完成执行之后
  • @AfterThrowing:异常通知,抛出异常之后
  • @Around:环绕通知

二 Advice应用实例

通过环绕通知获取方法执行时间

@Component
@Aspect
public class RepositoryAspect {
    @Pointcut("execution(* com.repository..*(..))")
    private void crud() {
    }
    //环绕通知
    @Around("crud()")
    public Object logPerformance(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTimes = System.currentTimeMillis();
        Object result = null;
        String name = "-";
        try {
            name = joinPoint.getSignature().toShortString();
            result = joinPoint.proceed();
            return result;
        } catch (Throwable t) {
            throw t;
        } finally {
            long duration = System.currentTimeMillis() - startTimes;
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(name);
            System.out.println(stringBuilder+"执行时间为"+duration)
        }
    }
}
public class AbstractAspect {
	protected ThreadLocal<Map<String, Object>> threadLocal = new ThreadLocal<>();
	protected ThreadLocal<Map<String, Object>> getThreadLocal(){
		if (threadLocal.get() == null){
			threadLocal.set(new HashMap<>());
		}
		return threadLocal;
	}
}
@Component
@Aspect
public class ControllerAspect extends AbstractAspect {
    //对于controller包下所有类和方法进行获取,除被注解NoHealth标注的类除外。
    @Pointcut("execution(* com.controller..*(..))&&!@annotation(NoHealth)")
    private void controllerPointCut() {
    }
    //在方法执行之前对参数进行处理 
    @Before(value = "controllerPointCut()")
    public void doBefore(JoinPoint joinPoint) {
        try {
            getThreadLocal().get().put(joinPoint.getSignature().toString(), System.currentTimeMillis());
            Object[] args = joinPoint.getArgs();
            MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
            String[] parameterNamesArray = methodSignature.getParameterNames();
            int i = 0;
            List<String> argsList = new ArrayList<>();
            if (!ObjectUtils.isEmpty(args)) {
                for (Object object : args) {
                    if (ObjectUtils.isEmpty(object)
                            || (object instanceof BeanPropertyBindingResult)
                            || (object instanceof HttpServletResponse)
                            || (object instanceof Boolean)
                            || (object instanceof String)
                            || (object instanceof Integer)) {
                        if ((object instanceof Boolean) || (object instanceof String) || (object instanceof Integer)) {
                            StringBuilder stringBuilder = new StringBuilder();
                            stringBuilder.append("{\"");
                            stringBuilder.append(parameterNamesArray[i]);
                            stringBuilder.append("\":\"");
                            stringBuilder.append(object);
                            stringBuilder.append("\"}");
                            argsList.add(JSONObject.fromObject(String.valueOf(stringBuilder)).toString());
                        }
                        i++;
                        continue;//跳出当前循环,且不执行此语句后面的语句!
                    }
                    if (!(object instanceof HttpServletRequest)) {
                        argsList.add(JSONObject.fromObject(object).toString());
                    } else {
                        HttpServletRequest request = (HttpServletRequest) object;
                        Enumeration<String> parameterNames = request.getParameterNames();
                        Map<String, String> argsMap = new HashMap<>();
                        while (parameterNames.hasMoreElements()) {
                            String elementName = parameterNames.nextElement();
                            argsMap.put(elementName, request.getAttribute(elementName).toString());
                        }
                        if (!ObjectUtils.isEmpty(argsMap)) {
                            argsList.add(JSONObject.fromObject(argsMap).toString());
                        }
                    }
                    i++;
                }
            }
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.append(JSONArray.fromObject(argsList));
        } catch (Exception e) {
        }
    }
    //对方法执行之后的返回值进行某种操作
    @AfterReturning(value = "controllerPointCut()", returning = "response")
    public void responseLog(JoinPoint joinPoint, Object response) {
        try {
            if (response == null) {
                response = new Object();
            }
            long duration = System.currentTimeMillis() - (Long) threadLocal.get().get(joinPoint.getSignature().toString());
            StringBuilder stringB uilder = new StringBuilder();
            stringBuilder.append(JSONObject.fromObject(response));
        } catch (Exception e) {
        }
    }
    //对方法抛出的异常进行操作
    @AfterThrowing(value = "controllerPointCut()", throwing = "e")
    public void exceptionLog(Exception e) {
    }
}

根据这些实例就可以参照写一些简单的SpringAOP实例了!

到此这篇关于SpringAop中的Advice通知详解的文章就介绍到这了,更多相关Advice通知内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot使用外置tomcat启动方式

    springboot使用外置tomcat启动方式

    这篇文章主要介绍了springboot使用外置tomcat启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-11-11
  • Logstash配置Java日志格式的方法小结

    Logstash配置Java日志格式的方法小结

    Logstash 是用于日志收集的开源工具,通常与 Elasticsearch 和 Kibana 一起使用,形成 ELK Stack,Logstash 非常灵活,可以通过配置文件(通常是 .conf 文件)来定义数据的输入、处理和输出,本文给大家介绍了Logstash配置Java日志格式的方法,需要的朋友可以参考下
    2024-09-09
  • SpringBoot Event实现异步消费机制的示例代码

    SpringBoot Event实现异步消费机制的示例代码

    这篇文章主要介绍了SpringBoot Event实现异步消费机制,ApplicationEvent以及Listener是Spring为我们提供的一个事件监听、订阅的实现,内部实现原理是观察者设计模式,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2024-04-04
  • springboot2整合redis使用lettuce连接池的方法(解决lettuce连接池无效问题)

    springboot2整合redis使用lettuce连接池的方法(解决lettuce连接池无效问题)

    这篇文章主要介绍了springboot2整合redis使用lettuce连接池(解决lettuce连接池无效问题),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 五种JAVA GUI布局管理的方式

    五种JAVA GUI布局管理的方式

    这篇文章主要介绍了JAVA几种GUI布局管理的相关知识,文中代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • 完美解决java读取大文件内存溢出的问题

    完美解决java读取大文件内存溢出的问题

    下面小编就为大家带来一篇完美解决java读取大文件内存溢出的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • java多线程三种上锁方式小结

    java多线程三种上锁方式小结

    本文主要介绍了java多线程三种上锁方式小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-12-12
  • 利用Java实现网站聚合工具

    利用Java实现网站聚合工具

    互联网上有数以万亿计的网站,每个网站大都具有一定的功能。搜索引擎虽然对互联网上的部分网站建立了索引,但是其作为一个大而全的搜索系统,无法很好的定位到一些特殊的需求。因此本文将介绍一个用java实现的网站数据聚合工具,需要的可以参考一下
    2022-01-01
  • Java序列化反序列化原理及漏洞解决方案

    Java序列化反序列化原理及漏洞解决方案

    这篇文章主要介绍了Java序列化反序列化原理及漏洞解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-08-08
  • Java实现文件上传至服务器的方法

    Java实现文件上传至服务器的方法

    这篇文章主要为大家详细介绍了Java实现文件上传至服务器的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01

最新评论