• 9、统一记录日志(AOP)


    1、AOP

    AOP,即面向切面编程,切面是一个一个组件。业务Bean是一个一个target。我们要先声明切点的位置,再通知要做什么事。只需要对切面组件编程即可,不需要再进到业务Bean中取改,提高了编程效率。
    在这里插入图片描述
    框架为切面提供了织入的功能,有编译时(运行快),类装载,运行时织入(慢些)。
    Aspect切面:

    • 注解@Component @Aspect
    • 声明切点的位置@Pointcut(切点的位置:返回值 包.类.方法.参数) pointcut()
    • 通知具体逻辑,5个注解@Before @After AfterReturning @AfterThrowing @Around
      Target: 是业务Bean
      在这里插入图片描述
      AOP实现的两种方式:
      AspectJ和Spring AOP。一般用后者,它是运行时织入,通过代理的方式,只在方法处有连接点。

    Spring AOP有两种动态代理方式:
    **为什么要代理:**在织入切面代码时,不在原来的实例中织入,而是在代理对象中织入。调用时也是掉哟个代理对象,而不是调用原始对象。容器调用对象,如果有AOP作用,就调用代理对象。

    JDK动态代理(自带的)和CGLib动态代理(第三方)。前者生成接口的实现类,在代理实例中织入,要求必须有业务接口;后者在业务不存在接口时,创建子类实例以实现代理。

    2、使用演示

    AlphaAspect

    //@Component
    //@Aspect
    public class AlphaAspect {
    
        // 切点:返回值 包 类 方法 参数
        @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
        public void pointcut() {
    
        }
    
        // 通知:连接点前、后、返回值、抛异常、连接点前后。
        @Before("pointcut()")// 针对该切点pointcut()
        public void before() {
            System.out.println("before");
        }
    
        @After("pointcut()")
        public void after() {
            System.out.println("after");
        }
    
        @AfterReturning("pointcut()")
        public void afterRetuning() {
            System.out.println("afterRetuning");
        }
    
        @AfterThrowing("pointcut()")
        public void afterThrowing() {
            System.out.println("afterThrowing");
        }
    
        @Around("pointcut()")
        public Object around(ProceedingJoinPoint joinPoint) throws Throwable {// 参数:连接点
            System.out.println("around before");
            Object obj = joinPoint.proceed();// 连接点调用目标组件的方法,返回目标组件的返回值
            System.out.println("around after");
            return obj;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    3、统一记录日志

    ServiceLogAspect

    @Component
    @Aspect
    public class ServiceLogAspect {
    
        private static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);
    
        @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
        public void pointcut() {
    
        }
    
        @Before("pointcut()")
        public void before(JoinPoint joinPoint) {// 参数:连接点
            // 用户[1.2.3.4],在[xxx],访问了[com.nowcoder.community.service.xxx()].
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletRequest request = attributes.getRequest();
            String ip = request.getRemoteHost();
            String now = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
            String target = joinPoint.getSignature().getDeclaringTypeName() + "." +joinPoint.getSignature().getName();// 得到该连接点的类名和方法名
            logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, now, target));
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

  • 相关阅读:
    OpenCV图像处理方法:腐蚀操作
    Python网页开发神器fac 0.2.8、fuc 0.1.28新版本更新内容介绍
    代码随想录 -- day56 -- 583. 两个字符串的删除操作 、72. 编辑距离
    nginx配置vue前端代理
    记录一次时序数据库的实战测试
    以数据为中心的安全市场快速增长
    基于Python的电子病历实体识别系统
    计算机毕业设计 基于协调过滤算法的绿色食品推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
    cmake 处理与平台相关的源代码
    vue项目调用多个不同的ip接口
  • 原文地址:https://blog.csdn.net/nice___amusin/article/details/126064337