`
umgsai
  • 浏览: 103574 次
  • 性别: 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();

}
 

 

分享到:
评论
发表评论

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

相关推荐

    JAVA 中Spring aop 实现日志记载

    该压缩包中包含了一个myeclipse6.5下开发的JAVA基于spring实现的日志记载例子,该例子提供了接受切点参数,解析切点返回值,并且都打印出来了,有详细的文档介绍。

    aop-log:项目正式命名为aop-log,基于Spring AOP,ThreadLocal实现方法埋点,埋点信息记录和自定义收集

    AopLogAopLog是基于SpringAop和ThreadLocal实现的一个对请求方法埋点记录与处理的日志工具包。设计目的和场景:使用Spring Aop拦截程序,基本上都是同一个小异,不想日后每个项目都柏林都写一份这样的Aop拦截处理...

    spring hibernate 日志管理插件

    功能日志:基于java aop思想设计,通过Spring advisorAutoProxy(自动代理)实现controller过滤代理拦截,并提供拦截filter过滤,支持spring EL表达式。 数据日志:设计中提供数据日志注入接口,管理数据日志注入,...

    基于切面的日志记录SSMdemo

    基于切面的日志记录SSMdemo,简单学习案例

    基于Spring Boot构建的HTTP请求日志记录和重试补偿工具(95分以上课程大作业).zip

    2. Spring MVC框架:Spring MVC是基于Spring框架的Web框架,用于开发Web应用程序。它采用MVC(Model-View-Controller,模型-视图-控制器)的架构模式,将应用程序分为模型层、视图层和控制器层,提供了处理请求、...

    controller-logger:用于Spring Boot的基于AOP的API日志记录

    在处理基于Spring的Web应用程序项目时,它很快变得烦人,为每个要创建的新控制器方法添加相同的日志语句。 在团队中工作也使人们忘记或添加未经格式化的日志变得不一致。 这是AOP(面向方面​​编程)的完美用例。 ...

    开发者突击·精通AOP整合应用开发 源码

    Spring AOP:以loC为基础讲解Spring下的AOP开发,讲解了3种AOP的开发方式,即使用@Aspect注释符、基于Schema的配置的开发方式和Spring API的开发方式,最后在实际的Java EE项目中实现5种Spring AOP功能(日志记录器...

    eclair:Java Spring库用于声明式日志记录

    Eclair-用于AOP日志记录的Java Spring库。 提供用于注释性方法执行的声明式日志记录的注释。 包括用于批注处理的抽象,简单的实现以及具有自动配置的Spring Boot启动程序。 特征 Spring AOP检测到的事件日志记录:...

    spring-boot mybaits spring security redis整合

    aop日志记录。 4、调度 ====== Spring task, 可以查询已经注册的任务。立即执行一次任务。 5、缓存和Session =========== 注解redis缓存数据,Spring-session和redis实现分布式session同步(建议按功能模块...

    SpringBoot开发实战(实战案例)

    案例08 AOP方式实现日志记录 案例09 基于JdbcTemplate的学生信息维护 案例10 Maven入门案例 案例11 基于Maven构建实现学生新增 案例12 Spring MVC入门案例 案例13 Spring MVC参数传递 案例14 Spring MVC文件上传 ...

    springmvc+hibernate 日志管理工具

    功能日志:基于java aop思想设计,通过Spring advisorAutoProxy(自动代理)实现controller过滤代理拦截,并提供拦截filter过滤,支持spring EL表达式。 数据日志:设计中提供数据日志注入接口,管理数据日志注入,...

    基于Struts2+Hibernate+Spring框架的超市信息管理系统

    项目作品名称: 基于Struts2+Hibernate+Spring框架的超市信息管理系统 使用JQuery datatable插件浏览从数据库查询的信息记录...用Spring AOP技术,实现对添加或修改数据库记录操作的日志功能,日志记录保存在数据库。

    基于SpringBoot2+Jpa+SpringSecurity+redis+Vue的前后端分离系统

    系统日志 记录用户访问监控异常信息 系统缓存管理 将redis的操作可视化,提供对redis的基本操作 Sql监控 采用 druid 监控数据库访问性能 技术栈 基础框架:Spring Boot 2.1.0.RELEASE 持久层框架:Spring boot Jpa ...

    spring-boot mybaits shiro redis整合

    aop日志记录。 4、调度 ====== Spring task, 可以查询已经注册的任务。立即执行一次任务。 5、缓存和Session =========== 注解redis缓存数据,Spring-session和redis实现分布式session同步(建议按功能模块...

    ssm_traveller:基于ssm的旅游后台管理系统,使用AdminLTE 前端框架,实现基本的CRUD功能,使用spring-security进行用户登录权限控制,利用spring aop记录访问日志

    旅游后台管理系统 1、项目环境 IDEA 2018.2 Mysql 5.5.27 jdk1.8 tomcat7 2、如何启动 1、在启动位置,配置maven,模块为ssm_web,使用tomcat7:run启动 2、网址: ​ 用户:admin 密码:123

    vip会员登录系统结合spring + mvc +hibernate

    其中包含apache的log4j记录日志信息,spring管理组件,springmvc分层,springaop配置数据库事务控制,hibernate二级缓存配置,实现了查询,用户登录注册,请求验证是否登录等基础功能Demo,基于后台测试,使用前台...

    JavaSpring的商城项目前台+后台+api

    这有助于增加模块化,并且可以用于事务管理、日志记录等。 事务管理:Spring提供了一致的事务管理接口,可以在JTA(Java Transaction API)或非托管环境中使用,简化了事务管理代码。 模型-视图-控制器(MVC):...

    项目管理-Spring学习源码

    面向切面编程(AOP):Spring 提供了 AOP 支持,能够帮助开发者实现横切关注点的模块化,如日志记录、事务管理等,提高了代码的模块化程度。 事务管理:Spring 提供了强大而灵活的事务管理支持,可以通过声明式事务...

    项目管理-spring6学习源码

    面向切面编程(AOP):Spring 提供了 AOP 支持,能够帮助开发者实现横切关注点的模块化,如日志记录、事务管理等,提高了代码的模块化程度。 事务管理:Spring 提供了强大而灵活的事务管理支持,可以通过声明式事务...

    项目管理-spring6学习源码(二)

    面向切面编程(AOP):Spring 提供了 AOP 支持,能够帮助开发者实现横切关注点的模块化,如日志记录、事务管理等,提高了代码的模块化程度。 事务管理:Spring 提供了强大而灵活的事务管理支持,可以通过声明式事务...

Global site tag (gtag.js) - Google Analytics