`
umgsai
  • 浏览: 111922 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

基于Spring AOP的日志记录

 
阅读更多

xml配置拦截器

 

<bean id="operationAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
  <property name="interceptorNames">
     <list><value>recordHistoryInterceptor</value></list>
  </property>
  <property name="beanNames">
  	 <list>
       <value>podUnitMemberService</value>
   </list>
  </property>
</bean>

 

<bean id="recordHistoryInterceptor" class="com.umgsai.interceptor.RecordHistoryInterceptor" />

 

public class RecordHistoryInterceptor implements MethodInterceptor {
    @Setter
    private HistoryRecorder historyRecorder;

    public Object invoke(MethodInvocation invocation) throws Throwable {
        Object result = null;
        try {
            result = invocation.proceed();
        } catch (Exception e) {
            result = e.getMessage();
            throw e;
        } finally {
            historyRecorder.recordHistory(invocation.getMethod(), invocation.getArguments(), result);
        }
        return result;
    }
}

 

 

    public void recordHistory(Method method, Object[] params, Object result) throws Throwable {
        OperationRecord annotation = method.getAnnotation(OperationRecord.class);
        if (annotation != null) {
            if (params.length > 0) {
                try {
                    //1. 如果dataType是GLOBAL
                    if (annotation.dataType() == DataTypeEnum.GLOBAL) {
                        recordProject(annotation, params, result);
                    } else {//2. 如果dataType不是GLOBAL,如BASIC,APP_RELATE
                        recordApp(annotation, method, params, result);
                    }
                } catch (Exception e) {
                    logger.error("recordHistory error:" + e.getMessage(), e);
                }
            } else {
                logger.warn("含有注解@OperationRecord的方法" + method.getName() + "没有包含参数!");
            }
        }
    }

 

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OperationRecord {
    OperationTypeEnum operationType();

    DataTypeEnum dataType();
}

 

public interface PodUnitMemberService {

//podUnitAppName为podUnitMember类中的属性
    @OperationRecord(dataType = DataTypeEnum.BASIC, operationType = OperationTypeEnum.INSERT)
    long insert(@IdentifierAnnotation(name = "podUnitAppName") PodUnitMember podUnitMember);
}

 

    private void recordApp(OperationRecord annotation, Method method, Object[] params, Object result)
                                                                                                     throws Throwable {
        ZappinfoOperationLogDO operationLogDO = new ZappinfoOperationLogDO();
        //2.1 设置dataType为注解里的dataType
        operationLogDO.setDataType(annotation.dataType().getCode());
        //2.2 获取参数注解信息
        Annotation[][] paraAnnotationArray = method.getParameterAnnotations();
        //2.3 遍历参数注解信息
        Object identifier = null;
        for (int index = 0; index < paraAnnotationArray.length; index++) {
            for (Annotation anno : paraAnnotationArray[index]) {
                //2.3.1 如果注解是TargetAnnotation
                if (anno instanceof TargetAnnotation) {
                    //2.3.1.1 appName是从参数中获取
                    if (((TargetAnnotation) anno).targetSource() == TargetSourceEnum.PARAMETER) {
                        operationLogDO.setAppName(params[index].toString());
                        //2.3.1.2 appName是从参数的属性中获取,通过反射调用getAppName方法
                    } else if (((TargetAnnotation) anno).targetSource() == TargetSourceEnum.ATTRIBUTE) {
                        operationLogDO.setAppName(params[index].getClass()
                            .getDeclaredMethod("getAppName").invoke(params[index]).toString());
                    }
                    //2.3.2 如果注解是DataTypeAnnotation
                } else if (anno instanceof DataTypeAnnotation) {
                    String dataType = null;
                    if (((DataTypeAnnotation) anno).dataTypeSource() == DataSourceTypeEnum.CLASS) {
                        dataType = dataTypeMap.get(params[index].getClass());
                    } else if (((DataTypeAnnotation) anno).dataTypeSource() == DataSourceTypeEnum.STRING) {
                        dataType = dataTypeMap.get(params[index]);
                    }
                    if (StringUtil.isNotBlank(dataType)) {
                        operationLogDO.setDataType(dataType);
                    } else {
                        logger.warn("没有找到" + params[index].getClass() + "对应的数据类型!");
                    }
                } else if (anno instanceof IdentifierAnnotation) {
                    //通过IdentifierAnnotation注解获取名称
                    IdentifierAnnotation idanno = (IdentifierAnnotation) anno;
                    String name = idanno.name();
                    identifier = params[index];
                    if (StringUtil.isNotBlank(name)) {
                        Object obj = params[index];
                        Field field = obj.getClass().getDeclaredField(name);
                        field.setAccessible(true);
                        //去注解中配置的属性名称的值
                        identifier = field.get(obj);
                    }
                }
            }
        }
        if (identifier == null) {
            fillDO(operationLogDO, annotation, params, result);
            zappinfoOperationLogDAO.insertOperatinoLog(operationLogDO);
            identifier = operationLogDO.getAppName();
        }
        addOperationRecord(annotation, identifier, method, params, result);
    }
 
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface IdentifierAnnotation {

    String name();

}
 

 

分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    spring aop实现接口参数变更前后对比和日志记录

    spring aop实现接口参数变更前后对比和日志记录完整代码,拿到项目代码,只需要做数据库连接的修改即可运行起来使用,代码案例详细,真是可靠,代码原文地址:...

    spring aop jar 包

    1. **切面(Aspect)**:切面是关注点的模块化,比如日志记录、事务管理、性能监控等。在Spring AOP中,切面由通知(Advice)和切点(Pointcut)定义。 2. **通知(Advice)**:通知是在特定连接点(Join Point)...

    Spring-AOP.rar_spring aop 日志

    Spring AOP,全称为Aspect-Oriented Programming,是Spring框架中的一个重要组成部分,主要用来处理系统的横切关注点,如日志记录、事务管理、性能监控等。这些关注点通常会分散在应用程序的各个角落,而AOP就是为了...

    JAVA 中Spring aop 实现日志记载

    在Java开发中,Spring AOP(面向切面编程)是一个强大的功能,用于实现日志记录。AOP允许我们在不修改原有代码的情况下,插入新的行为,比如日志记录,事务管理等。下面将详细介绍如何在Spring框架中使用AOP来实现...

    spring AOP日志框架

    总结来说,Spring AOP日志框架允许我们通过注解方式轻松地实现业务日志管理,提高代码的可读性和可维护性,同时减少了代码冗余。通过自定义切面和通知,我们可以灵活地控制日志记录的时机和内容,满足不同场景的需求...

    基于Spring AOP的工具包

    例如,我们可以定义一个切面来处理日志记录,这样就无需在每个被记录的方法中插入日志代码。只需在切面中定义切入点(pointcut)表达式,匹配需要记录日志的方法,然后在通知(advice)中编写日志逻辑即可。 在实际...

    Spring AOP实现机制

    - **日志记录**:在方法调用前后记录操作信息。 - **事务管理**:自动进行事务的开启、提交、回滚等操作。 - **权限控制**:在访问敏感资源前进行权限检查。 - **性能监控**:记录方法执行时间,分析系统性能瓶颈。 ...

    spring aop 五个依赖jar

    Spring AOP(面向切面编程)是...这样,我们可以保持业务逻辑的清晰,同时实现系统级的服务,如事务管理、日志记录、性能监控等。在实际项目中,正确配置和使用这些依赖库,对于实现高效、灵活的面向切面编程至关重要。

    spring-aop实例

    9. **应用场景**:Spring AOP常用于日志记录、事务管理、性能监控、安全性控制等。例如,你可以定义一个切面来记录所有服务层方法的调用,或者在每次数据库操作前开启事务并在操作成功后提交事务。 通过以上介绍,...

    基于java的企业级应用开发:Spring AOP简介.ppt

    1. **Aspect**:切面是AOP的核心概念,它封装了特定的横切关注点,例如事务管理和日志记录。一个切面可以包含多个通知(Advice)和切点(Pointcut)。 2. **Joinpoint**:连接点是指程序执行过程中的一个特定时刻,...

    spring aop的demo

    在`springAop1`这个压缩包中,可能包含了一个简单的应用示例,展示了如何定义一个切面类,以及如何在该类中定义通知方法。例如,我们可能会看到一个名为`LoggingAspect`的类,其中包含了`@Before`注解的方法,用于在...

    Spring AOP的简单实现

    在这个场景中,我们将使用Spring AOP来实现一个日志记录的功能,以追踪系统中各个方法的调用情况,包括访问时间以及传递的参数。下面将详细阐述如何实现这一目标。 首先,我们需要了解AOP的基本概念。AOP的核心是切...

    springAOP所需jar包

    在Java应用中,AOP主要用于日志记录、性能统计、安全控制、事务管理等方面,通过将这些通用功能模块化,可以避免重复代码,提高代码的可维护性和复用性。 Spring AOP的实现基于动态代理,有两种代理方式:JDK动态...

    基于xml的SpringAOP实例

    5. **运行与测试**:完成以上步骤后,启动Spring容器,当`MyService`的方法被调用时,将会先执行`logBefore`方法的日志记录。 通过这种方式,Spring AOP允许我们在不修改业务代码的情况下,轻松地添加和管理横切...

    spring AOP入门教程

    AOP是一种编程范式,旨在解决程序中的横切关注点问题,这些关注点通常与业务逻辑无关,但又需要在多个地方被调用,如日志记录、性能统计、异常处理等。AOP通过将这些关注点与核心业务逻辑分离,使得代码更加模块化...

    SpringAOP.rar_springAOP

    其中,Spring AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的重要组成部分,它为开发者提供了在不侵入业务代码的情况下,进行日志记录、性能监控、事务管理等横切关注点的能力。本文将深入探讨...

    spring aop所需jar包

    在Java应用程序中,AOP主要用于日志记录、性能统计、安全控制、事务管理等跨切面的关注点。下面将详细介绍Spring AOP的关键知识点以及与其相关的jar包。 1. **AOP概念**: - **切面(Aspect)**:AOP的核心概念,...

    springAOP配置动态代理实现

    Spring AOP(面向切面编程)是Spring框架的重要组成部分,它允许程序员在不修改源代码的情况下,通过在运行时插入额外的行为(如日志记录、性能监控等)来增强对象的功能。动态代理则是Spring AOP实现的核心技术之一...

    Spring Aop使用实例

    Spring AOP有两种实现方式:基于代理的AOP(JDK动态代理和CGLIB代理)和基于注解的AOP。 - **JDK动态代理**:当目标类实现了接口时,Spring会使用JDK的Proxy类创建一个代理对象,该代理对象会在调用接口方法时插入...

    spring AOP入门实例

    在这个入门实例中,我们将深入理解Spring AOP如何实现简单日志记录。 首先,AOP的核心概念包括切面(Aspect)、通知(Advice)、连接点(Join Point)、切入点(Pointcut)和织入(Weaving)。切面是AOP中的核心...

Global site tag (gtag.js) - Google Analytics