1、主要实现用户在进行某项操作时,多数据库的更新、插入和删除详细信息。记录操作时的请求信息。
2、在进入Controller时,生成一个事物ID,在这个Controller中进行的所有DAO操作都绑定该事物ID。并进行记录日志信息。
package com.centralsoft.filter; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Date; import java.util.HashMap; import java.util.regex.Pattern; import net.sf.json.JSONObject; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Component; import com.centralsoft.cache.CacheService; import com.centralsoft.cache.annotations.Cache; import com.centralsoft.cache.entity.MemCacheKey; import com.centralsoft.entity.SysLogDetail; import com.centralsoft.manager.pub.ThreadBean; import com.centralsoft.manager.pub.ThreadId; import com.centralsoft.pub.dao.SysLogDAO; import com.centralsoft.webservice.pub.DateSHA; /** * DAO层AOP拦截器,实现记录用户操作过的所有方法和参数,并实现DAO层缓存 * * @author Administrator * */ @Aspect @Component public class AspectAutoDAOBean { @Autowired @Qualifier("CacheService") private CacheService memcache; @Autowired @Qualifier("SysLogDAO") private SysLogDAO SysLogDAO; @Around("execution(* com.centralsoft.*.dao.Zr*DAO.*(..))") public Object before(ProceedingJoinPoint joinPoint) throws Throwable { // 获取请求事务ID信息 ThreadId threadId = new ThreadBean().getThreadId(); // 调用方法名称 String methodName = joinPoint.getSignature().getName(); // 调用参数 Object[] args = joinPoint.getArgs(); Object object = null; // 数据库更新操作日志 if (Pattern.matches("(save|insert|add|delete|remove|del|update)[\\S]*", methodName)) { if (threadId != null && threadId.getTransactionalId() != null) { // 获取执行请求事务ID String transactionalId = threadId.getTransactionalId(); // 获取执行请求用户ID String userId = threadId.getUserId(); SysLogDetail sysLogDetail = new SysLogDetail(); sysLogDetail.setXh(transactionalId); sysLogDetail.setUserId(userId); sysLogDetail.setMethod(methodName); JSONObject msg = new JSONObject(); // 处理参数 for (Object temp : args) { // 获取参数类型,不同参数类型数据处理不一样 Class<? extends Object> paramClazz = temp.getClass(); String classType = paramClazz.getName(); if (classType.equals("java.lang.String")) { msg.put("key", temp); } else if (classType.equals("java.util.HashMap")) { msg.putAll((HashMap<?, ?>) temp); } else if (classType.startsWith("com.")) { try { Field[] f = paramClazz.getDeclaredFields(); for (Field field : f) { String fieldName = field.getName(); field.setAccessible(true); msg.put(fieldName, field.get(temp)); } } catch (SecurityException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } } } sysLogDetail.setMsg(msg.toString()); // 记录DAO数据库操作日志 SysLogDAO.insertSysLogDetail(sysLogDetail); } // 执行数据库操作 object = joinPoint.proceed(); // 数据库查询缓存 } else if (Pattern.matches("(query|load|get|select|read)[\\S]*", methodName)) { // DAO层缓存注解 MemCacheKey cacheKey = new MemCacheKey(); // 获取cache注解属性 Cache cache = null; // 获取请求方法 Class<?> cls = joinPoint.getTarget().getClass(); // 获取class中的所有方法 Method[] methods = cls.getMethods(); for (Method m : methods) { // 获取执行方法前的注解信息。 if (m.getName().equals(methodName)) { cache = m.getAnnotation(Cache.class); break; } } if (cache != null) { // 获取memcacheKey,并进行MD5加密 cacheKey = memcacheKey(cache, args); // 判断缓存服务器是否存在该可以值 if (memcache.exist(cacheKey.getMemcacheKey())) { object = memcache.get(cacheKey.getMemcacheKey()); } else { // 执行数据库操作 object = joinPoint.proceed(); // 将数据存放进缓存 if (cacheKey.getMemcacheKey() != null) { memcache.put(cacheKey.getMemcacheKey(), object == null ? "" : object, new Date(cacheKey .getTime())); } } } else { // 执行数据库操作 object = joinPoint.proceed(); } } else { // 执行数据库操作 object = joinPoint.proceed(); } return object; } /** * 获取根据注解中的key获取memcache的含参数key值 * * @param cache * @param parameterObject * @return * @author fei.zhao 2011-10-10 */ @SuppressWarnings("unchecked") private static MemCacheKey memcacheKey(Cache cache, Object[] args) { MemCacheKey tempKey = new MemCacheKey(); String key = ""; boolean flag = true; StringBuilder keyBuilder = new StringBuilder(32); // 获取注解中的key值 String cacheKey = cache.key(); Object[] cacheArgs = cacheKey.split("\\."); // 设置请求参数在args[]中的序号 // key参数进行循环遍历 for (Object s : cacheArgs) { // 判断是否是格式$,$... if (s.toString().startsWith("$")) { // 获取参数名称 String type = s.toString().substring(1); // 获取参数值 Object temp = args[0]; // 获取参数类型,不同参数类型数据处理不一样 Class<? extends Object> paramClazz = temp.getClass(); String classType = paramClazz.getName(); if (classType.equals("java.lang.String")) { keyBuilder.append(temp); } else if (classType.equals("java.util.HashMap")) { keyBuilder.append(((HashMap) temp).get(type)); } else if (classType.startsWith("com.")) { try { Field f = paramClazz.getDeclaredField(type);// 实体中字段 f.setAccessible(true);// 允许访问私有字段 keyBuilder.append(f.get(temp)); } catch (SecurityException e) { flag = false; e.printStackTrace(); } catch (NoSuchFieldException e) { flag = false; e.printStackTrace(); } catch (IllegalArgumentException e) { flag = false; e.printStackTrace(); } catch (IllegalAccessException e) { flag = false; e.printStackTrace(); } } } else { keyBuilder.append(s); } // 每个参数后面添加 “.”号分隔 keyBuilder.append("."); } if (args.length == 3) { keyBuilder.append(args[1] + ".").append(args[2]); } if (flag == true) { key = keyBuilder.toString(); tempKey.setMemcacheKey(DateSHA.shaEncrypt(key)); tempKey.setTime(cache.time()); } return tempKey; } }
相关推荐
在Spring AOP中,切面可以通过注解或XML配置来定义。 - 连接点(Join Point):连接点是程序执行过程中的一个特定点,例如方法的调用或字段的访问。 - 切入点(Pointcut):切入点是连接点的集合,定义了切面将在...
SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...
总结一下,通过上述步骤,我们已经在Spring Boot应用中利用Spring AOP和注解方式实现了数据脱敏。这个拦截器可以在不修改原有业务代码的情况下,确保敏感信息在响应给客户端之前得到处理,提高了应用的安全性。同时...
本节将详细介绍如何使用Spring AOP实现流程日志跟踪,主要关注于如何通过AOP拦截特定的类和方法来进行日志记录。 ##### 3.1 配置Spring AOP 在Spring配置文件中定义切面和切入点表达式是非常关键的一步。一般来说...
本教程将详细介绍如何利用注解来配置和使用AOP来拦截Controller层的方法,以便记录执行过程中的相关信息,实现日志管理。 一、Spring AOP基础 AOP是Spring框架的核心组件之一,它允许程序员定义“切面”,这些切面...
本篇文章将深入探讨如何通过Spring的注解方式实现AOP的细节。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切点(Pointcut)定义了哪些方法会被通知(Advice...
"springaop拦截controller日志"这个主题旨在讲解如何使用Spring AOP来拦截Controller层的方法调用,并在方法执行前后记录相关日志。 首先,了解Spring AOP的基本概念。AOP是一种编程范式,它允许程序员定义“切面”...
在提供的压缩包中,可能包含了一个或多个测试类(Tests),这些测试类通常用来验证AOP拦截器的功能。它们可能包含模拟业务场景的方法,这些方法会被切面拦截并执行相应的通知。通过运行这些测试,我们可以确保AOP...
Spring提供了两种主要的AOP实现方式:基于代理(Proxy-based)和基于注解(Annotation-based)。 - **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行...
这个“spring AOP拦截方法小示例”是一个实际应用,展示了如何使用Spring AOP来拦截特定层的所有方法,并在调用前后以及出现异常时执行自定义逻辑。 首先,让我们了解AOP的基本概念。AOP的核心是切面(Aspect),它...
通过对这个简单的AOP拦截器实现的学习,我们可以进一步探索如何结合注解驱动的AOP、环绕通知(`Around Advice`)、代理模式的实现细节、以及如何在实际项目中利用AOP解决实际问题。AOP是Spring框架的强大工具,理解...
本文将详细介绍如何使用AspectJ注解在Spring MVC中实现AOP拦截Controller方法,并提供一个具体的例子。 首先,我们需要了解Spring AOP的基础概念。AOP允许我们定义“切面”,这些切面包含了业务逻辑中横切关注点的...
我们将详细探讨在"springaop-demo01"中实现的注解AOP以及"SSM-MybatisOneForOne-demo01"中的MyBatis一对一映射。 首先,让我们深入了解一下注解AOP在"springaop-demo01"中的应用。AOP(面向切面编程)是Spring框架...
Spring AOP 拦截器 Advisor 是 Spring 框架中的一个重要概念,它与切面编程密切相关,用于实现细粒度的控制和增强应用程序的行为。在 Spring AOP 中,Advisor 是一个组合了通知(Advice)和切入点(Pointcut)的对象...
在Spring框架中,Bean注解和AOP(面向切面编程)是两个核心概念,它们在实际开发中扮演着至关重要的角色。让我们深入探讨这两个主题。 首先,我们来看Bean注解。在Spring 4中,注解是配置Bean的主要方式,它提供了...
Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。在这个压缩包中,你可能会找到一系列用于支持Spring AOP以及相关技术如...
标题中的“在自定义Spring AOP中使用EL获取拦截方法的变量值”指的是在Spring的面向切面编程(AOP)中,通过Expression Language(EL,表达式语言)来访问被拦截方法的局部变量值。这通常涉及到Spring的代理机制、...
本篇文章将深入探讨如何使用注解方式在Spring AOP中实现内部方法的拦截。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它封装了横切关注点,即那些跨越多个对象的业务逻辑,如日志记录、事务管理...
例如,可能会有一个自定义的MyBatis拦截器用于分页查询,一个Spring AOP切面用于记录操作日志,Spring事务管理确保数据的一致性,而反射工具类可能用于动态加载配置或处理某些通用的反射任务。通过这些组件的组合,...