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; } }
相关推荐
springboot spring aop 拦截器 注解方式实现脱敏(涉及到:pom.xml -->application.properties --->启动类-->拦截器)
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想
Spring Mvc AOP通过注解方式拦截controller等实现日志管理
项目中含有一整个springboot实现aop的功能,在拦截的方法形式上有两种一种是通过切点设置为拦截某个包路径下面的类中的所有方法;还有一种是基于某个自定义注解的.
Spring MVC AOP通过自定义注解方式拦截Controller等实现日志管理, springMVC里做添加AOP拦截,用于捕获异常。
spring AOP,注解方式的实现! 内部方法的拦截
有人问 Sping AOP用AspectJ注解的方式拦截不到SpringMVC的controller方法? 我这里提供了一种解决方法,仅供参考
演示了使用spring aop拦截方法进行数据验证,并结合注解实现
NULL 博文链接:https://conkeyn.iteye.com/blog/2354644
网上很不容易找到的关于AOP拦截EL表达式的正确打开方式,比如:http://www.cnblogs.com/ph123/p/5631030.html这种根本就不准确
Spring MVC AOP通过注解方式拦截Controller等实现日志管理demo版本2
SpringBoot下的Spring——DAY04——动态代理总结、AOP、自定义注解进行拦截、动态获取注解参数、通知方法 1.动态代理总结 1.1 JDK动态代理特点 1.2 CGlib动态代理 1.2.1 CGLib特点说明 1.3 动态代理的作用 2 Spring...
SpringBoot-自定义注解AOP实现及拦截器示例代码
<aop:aspect id="aspect" ref="logIntercepter"> 引入具体的AOP操作类 <aop:pointcut expression="execution(* com.spring.service..*(..))" id="pointCut"/>声明一个切入点,注意execution表达式的写法 <aop:before ...
- Spring Boot 数据库操作,包括SpringJDBC、JPA、Mybatis注解版 & XML版、MongoDB。其中,每个版本都有其对应的多数据源解决方案。 - springboot-caches - Spring Boot 缓存,包括redis、ehcache、spring-cache...
注解包含: 拦截器 , 过滤器 , 序列化 , @After , @AfterReturning , @AfterThrowing , @annotation , @Around , @Aspect , @Autowired , @Bean , @Before , @Component , @ComponentScan , @ComponentScans , @...
@Autowired:Spring提供的注解 @Inject:JSR-330提供的注解 @Resource:JSR-250提供的注解 Java配置 @Configuration声明当前类是一个配置类 @Bean注解在方法上,声明当前方法的返回值为一个...
基于注解与 XML 配置文件两种形式的 AOP demo。 基于 xml 配置文件的 aop 管理 ```xml <!-- 配置切面的bean --> <bean id="loggingAspect" class="com.jas.aop.xml.LoggingAspect"/> <aop:config> <!...
内含有mybatis 拦截器实现的分页代码,spring 的事务和aop 测试、和反射工具类
SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例SpringBoot AOP各种注解、自定义注解、鉴权使用案例