当前位置:   article > 正文

【项目】仿牛客网社区开发 第3章 Spring Boot 实践 开发社区核心功能 10 统一记录日志_仿牛客社区 第三章 总结

仿牛客社区 第三章 总结

【项目】仿牛客网社区开发

在这里插入图片描述

第3章 Spring Boot 实践 开发社区核心功能

10 统一记录日志
10.1 需求
  • 帖子模块
  • 评论模块
  • 消息模块

在这里插入图片描述

硬编码的方法会导致耦合度太高,不易修改。

10.2 AOP的概念
  • Aspect Oriented Programing, 即面向方面(切面)编程。
  • AOP是一种编程思想,是对OOP的补充, 可以进一步提高编程的效率。

在这里插入图片描述

代码使用简单,重点理解这种思想

【单独定义组件】

这个组件不会与我们的已有系统发生关系,不需要额外的去主动调用。

10.3 AOP的术语

在这里插入图片描述

  • Target:目标对象,我们要处理的需求的目标【程序中已经开发好的一个个bean 】
  • Aspect:切面,业务需求【一个额外的bean,完成我们额外的需求】
    • Pointcut:切点【声明要织入到哪些目标对象的哪些位置】
    • Advice:通知【额外需求到底要做什么】
  • Joinpoint:连接点,织入位置【目标对象有很多地方可以被织入代码】
10.4 AOP的实现
  • AspectJ 【学习成本较高】
    • AspectJ是语言级的实现,它扩展了Java语言,定义了AOP语法。
    • AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码规范的class文件。
  • Spring AOP
    • Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器。
    • Spring AOP在运行时通过代理的方式织入代码只支持方法类型的连接点。 【虽然不全面,但是是一个性价比很高的解决方案】
    • Spring支持对AspectJ的集成
10.5 Spring AOP
  • JDK动态代理
    • Java提供的动态代理技术,可以在运行时创建接口的代理实例。
    • Spring AOP默认采用此种方式,在接口的代理实例中织入代码。
  • CGLib动态代理
    • 采用底层的字节码技术,在运行时创建子类代理实例。
    • 当目标对象不存在接口时,Spring AOP会采用此种方式,在子类实例中织入代码

代码体会:

package com.nowcoder.community.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @Projectname: community
 * @Classname: AlphaAspect
 * @Author: Ding Jiaxiong
 * @Date:2023/4/19 18:49
 */

@Component
@Aspect
public class AlphaAspect {

    // 定义切点
    @Pointcut("execution(* com.nowcoder.community.service.*.*(..))")
    public void pointcut() {

    }

    @Before("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
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53

在这里插入图片描述

这样就对所有的业务都生效了。

直接启动服务器,访问首页

在这里插入图片描述

可以看到,到处都是

在这里插入图片描述

当然因为我们代码中并没有报错,所以没有那两个throw 的输出。

【实现需求:记日志】

记录啥呢? 用户在xx 时间访问了xxx 方法。

package com.nowcoder.community.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Projectname: community
 * @Classname: ServiceLogAspect
 * @Author: Ding Jiaxiong
 * @Date:2023/4/19 19:02
 */

@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
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

直接重启服务器看看,访问首页

在这里插入图片描述

没问题,每一个业务都使用到了这个通知【在访问前】。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/572993
推荐阅读
相关标签
  

闽ICP备14008679号