美文网首页我爱编程
公共日志模块实现

公共日志模块实现

作者: JOHN_LIN | 来源:发表于2018-04-12 22:03 被阅读0次

    背景:存在A系统和N系统。N系统是一个公共系统,目前暂时只接入A系统,将来还会接入B系统,C系统等。

    image

    N系统分成众多子项目,现在其中的基础模块需要为其他模块提供日志插入功能,除此之外还需要将日志接入外部的A,B等系统提供。为什么要记录2份日志呢?emmm,原因我就不描述了,因为对理解这个文章不是很有必要,总之是研发和产品一堆人沟通下来的结果。

    一,设计思路:
    基础模块提供一个切面,以及一个自定义的Annotation,其他模块在需要记录日志的接口加上这个Annotation。基础模块除了在自身保存一份日志,还需要为A系统等外部系统保存,考虑到拓展性,为外部系统保存日志的时候,采用工厂模式。

    二,基础模块日志具体实现(这里仅描述对外提供的jar包):
    1,annotation

    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target( { ElementType.METHOD, ElementType.TYPE })
    public @interface OperateLogAnnotation {
    
    }
    

    2,切面类

    @Aspect
    public class ControllerOperateLogAspect
    {
             //调用外部系统的工厂类
        @Autowired
        private OperationLogFactory operationLogFactory;
        //省略其他。。。。。
    
        /**
         * 对有@LogOperation标记的方法,记录其执行参数及返回结果.
         */
        @Pointcut("@annotation(com.xxx.base.annotation.OperateLogAnnotation)")
        public void methodPointcut()
        {
        }
    
        @Around("methodPointcut()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable
        {
        
            Object obj = pjp.proceed();
            try
            {
                     //省略判断,只有调用成功才记录日志
                    // 成功后记录操作日志,记录在基础模块的日志
                    insertOperateLog();
                    // 插入外部系统日志
                    insertExternalOperationLog();
            }
            catch (Throwable e)
            {
                log.error("记录操作日志信息异常:", e);
            }
            return obj;
        }
      /**
       * 记录业务方日志
       */
        public void insertExternalOperationLog(String remark....) throws Throwable
        {
            //通过工厂获取具体的外部日志处理类
            OperationLogService operationLogService = operationLogFactory
                    .getOperationLogService(remark);
            operationLogService.insertOperationLog();
        }
    

    3,外部日志处理接口

    public interface OperationLogService
    {
        void insertOperationLog(....);
    
        String getRemark();
    }
    

    4,外部日志处理实现类(针对A系统的)

    public class XXOperationLog implements OperationLogService
    {
        @Autowired
        private ThreadPoolTaskExecutor operateLogThreadPool;
    
        public void insertOperationLog(....)
        {
              // 省略,使用线程池保存数据,不展开
            operateLogThreadPool
                    .execute(new XXOperationLogTask(..));
        }
    
        @Override
        public String getRemark()
        {
            return "xxxx";//这里返回A系统的标识
        }
    
    }
    
    如果后续N系统还要继续接入其他系统就再接入新加一个实现类。
    

    5,工厂类OperationLogFactory

    public class OperationLogFactory
    {
    
        @Autowired
        private List<OperationLogService> list;
    
        public OperationLogService getOperationLogService(String remark) throws Throwable
        {
            for (OperationLogService operationLogService : list)
            {
                if (operationLogService.getRemark().equals(remark))
                {
                    return operationLogService;
                }
            }
    
            throw new NoSuchBeanDefinitionException("没找到对应业务方的日志实现类,业务方remark:" + remark);
        }
    }
    

    工厂类这里使用的是集合注入,这也是我无意间了解到的,是不是很方便?list可以拿到这个接口的所有实现类。

    到这里基础模块的日志部分就完成了,然后就是N系统的其他模块(这个是日志记录发起者)的引用了。

    三,其他模块(日志记录发起者)的引用

    1,需要引入基础模块对外提供的jar包:
    使用maven坐标引入的方式。这里采用的dubbo的调用方式,如果没了解过的同学,可以把这个jar包当成第三方的工具,通过这个jar包就可以使用第三方的服务。
    2,注册相关的bean:
    ① 为切面类ControllerOperateLogAspect注册一个bean。
    ②为切面类ControllerOperateLogAspect中调用的基础模块日志功能的dubbo服务注册一个bean。
    (不过这里采用的是引入配置文件的方式,就是在项目中import基础模块jar包中配置好的xml配置文件,配置文件已经配置好了需要的bean,调用者不需要具体配置那些bean)
    3,在需要记录日志的接口上方加上注解@OperateLogAnnotation

    好了,整个流程结束啦,可以看看发起的日志是否写入了基础服务
    和A系统的数据库中。
    终于写完了


    公共日志模块实现

    相关文章

      网友评论

        本文标题:公共日志模块实现

        本文链接:https://www.haomeiwen.com/subject/uznfkftx.html