`

注解方式---spring的AOP拦截用户操作

 
阅读更多

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-jar

    在Spring AOP中,切面可以通过注解或XML配置来定义。 - 连接点(Join Point):连接点是程序执行过程中的一个特定点,例如方法的调用或字段的访问。 - 切入点(Pointcut):切入点是连接点的集合,定义了切面将在...

    springboot+aspect实现springaop拦截指定方法.zip

    SpringBoot结合AspectJ实现SpringAOP拦截指定方法的知识点涵盖了多个方面,这包括Spring AOP的基本概念、SpringBoot的应用、切点(Pointcut)与通知(Advice)的定义、自定义注解以及AspectJ的使用。以下是这些知识...

    springboot spring aop 拦截器注解方式实现脱敏

    总结一下,通过上述步骤,我们已经在Spring Boot应用中利用Spring AOP和注解方式实现了数据脱敏。这个拦截器可以在不修改原有业务代码的情况下,确保敏感信息在响应给客户端之前得到处理,提高了应用的安全性。同时...

    spring aop切面拦截指定类和方法实现流程日志跟踪

    本节将详细介绍如何使用Spring AOP实现流程日志跟踪,主要关注于如何通过AOP拦截特定的类和方法来进行日志记录。 ##### 3.1 配置Spring AOP 在Spring配置文件中定义切面和切入点表达式是非常关键的一步。一般来说...

    Spring Mvc AOP通过注解方式拦截controller等实现日志管理

    本教程将详细介绍如何利用注解来配置和使用AOP来拦截Controller层的方法,以便记录执行过程中的相关信息,实现日志管理。 一、Spring AOP基础 AOP是Spring框架的核心组件之一,它允许程序员定义“切面”,这些切面...

    使用Spring的注解方式实现AOP的细节

    本篇文章将深入探讨如何通过Spring的注解方式实现AOP的细节。 首先,我们需要了解AOP的基本概念。AOP的核心是切面(Aspect),它封装了跨越多个对象的行为或责任。切点(Pointcut)定义了哪些方法会被通知(Advice...

    springaop拦截controller日志

    "springaop拦截controller日志"这个主题旨在讲解如何使用Spring AOP来拦截Controller层的方法调用,并在方法执行前后记录相关日志。 首先,了解Spring AOP的基本概念。AOP是一种编程范式,它允许程序员定义“切面”...

    spring aop 拦截实例

    在提供的压缩包中,可能包含了一个或多个测试类(Tests),这些测试类通常用来验证AOP拦截器的功能。它们可能包含模拟业务场景的方法,这些方法会被切面拦截并执行相应的通知。通过运行这些测试,我们可以确保AOP...

    以注解方式模拟Spring IoC AOP

    Spring提供了两种主要的AOP实现方式:基于代理(Proxy-based)和基于注解(Annotation-based)。 - **基于代理的AOP**:Spring使用JDK动态代理或CGLIB动态代理创建目标对象的代理,代理对象在调用目标方法前后执行...

    spring AOP拦截方法小示例

    这个“spring AOP拦截方法小示例”是一个实际应用,展示了如何使用Spring AOP来拦截特定层的所有方法,并在调用前后以及出现异常时执行自定义逻辑。 首先,让我们了解AOP的基本概念。AOP的核心是切面(Aspect),它...

    spring aop 拦截器简单实现

    通过对这个简单的AOP拦截器实现的学习,我们可以进一步探索如何结合注解驱动的AOP、环绕通知(`Around Advice`)、代理模式的实现细节、以及如何在实际项目中利用AOP解决实际问题。AOP是Spring框架的强大工具,理解...

    spring MVC AOP注解方式如何拦截controller 例子

    本文将详细介绍如何使用AspectJ注解在Spring MVC中实现AOP拦截Controller方法,并提供一个具体的例子。 首先,我们需要了解Spring AOP的基础概念。AOP允许我们定义“切面”,这些切面包含了业务逻辑中横切关注点的...

    草稿:SSM整合-用springaop-demo01实现了注解AOP,SSM-MybatisOneForOne-demo01实现

    我们将详细探讨在"springaop-demo01"中实现的注解AOP以及"SSM-MybatisOneForOne-demo01"中的MyBatis一对一映射。 首先,让我们深入了解一下注解AOP在"springaop-demo01"中的应用。AOP(面向切面编程)是Spring框架...

    Spring AOP 拦截器 Advisor

    Spring AOP 拦截器 Advisor 是 Spring 框架中的一个重要概念,它与切面编程密切相关,用于实现细粒度的控制和增强应用程序的行为。在 Spring AOP 中,Advisor 是一个组合了通知(Advice)和切入点(Pointcut)的对象...

    Spring4--2.bean注解和AOP

    在Spring框架中,Bean注解和AOP(面向切面编程)是两个核心概念,它们在实际开发中扮演着至关重要的角色。让我们深入探讨这两个主题。 首先,我们来看Bean注解。在Spring 4中,注解是配置Bean的主要方式,它提供了...

    jar包---Spring AOP 还需.rar

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它提供了一种模块化和声明式的方式来实现横切关注点,如日志、事务管理、性能监控等。在这个压缩包中,你可能会找到一系列用于支持Spring AOP以及相关技术如...

    在自定义spring aop中使用el获取拦截方法的变量值。

    标题中的“在自定义Spring AOP中使用EL获取拦截方法的变量值”指的是在Spring的面向切面编程(AOP)中,通过Expression Language(EL,表达式语言)来访问被拦截方法的局部变量值。这通常涉及到Spring的代理机制、...

    Spring AOP 注解方式

    本篇文章将深入探讨如何使用注解方式在Spring AOP中实现内部方法的拦截。 首先,理解AOP的基本概念至关重要。AOP的核心是切面(Aspect),它封装了横切关注点,即那些跨越多个对象的业务逻辑,如日志记录、事务管理...

    mybatis 拦截器 + spring aop切面 + spring事务+ 反射工具类

    例如,可能会有一个自定义的MyBatis拦截器用于分页查询,一个Spring AOP切面用于记录操作日志,Spring事务管理确保数据的一致性,而反射工具类可能用于动态加载配置或处理某些通用的反射任务。通过这些组件的组合,...

Global site tag (gtag.js) - Google Analytics