AOP编程实现统一记录日志

什么是AOP

  • Aspect Oriented Programming
    面向切面编程
  • AOP是一种编程思想,是对OOP的补充
    可以进一步提高编程效率

AOP术语

在这里插入图片描述

  • Target:目标类
  • JoinPoint:连接点
    织入代码的位置
  • Weaving:织入
    – 编译时织入:效率高,但程序尚未运行对运行情况了解不详细不充分
    – 运行时织入:能够对运行的程序有充分的了解,但效率较低
  • Ascept:切面
    – pointCut:切点
    – Advice:实现具体逻辑的位置

非AOP编程的日志处理

public class AlphaService {
		public void doSomething() {
		//记录日志...
		//处理业务...
		}
}

需要在每个类或方法中添加日志记录工具,很麻烦

AOP的实现

  • AspectJ
    – AspectJ是语言级的实现,它扩展了Java语言,定义了AOP语法。
    – AspectJ在编译期织入代码,它有一个专门的编译器,用来生成遵守Java字节码规范的class文件。
  • Spring AOP
    – Spring AOP使用纯Java实现,它不需要专门的编译过程,也不需要特殊的类装载器。
    – Spring AOP在运行时通过代理的方式织入代码,只支持方法类型的连接点。
    – Spring支持对AspectJ的集成。

SpringAOP

  • JDK动态代理
    – Java提供的动态代理技术,可以在运行时创建接口的代理实例。
    – Spring AOP默认采用此种方式,在接口的代理实例中织入代码。
  • CGLib动态代理
    –采用底层的字节码技术,在运行时创建子类代理实例。
    – 当目标对象不存在接口时,Spring AOP会采用此种方式,在子类实例中织入代码。

具体实现

//@Component
//@Aspect
public class AlphaAspect {
	//声明切点(*[返回类型] com.duan.nowcoder.community.service[包名].*[类].*[方法](..[参数]))
    @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");
    }
	//兼顾Before和After
    @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;
    }
}

统一记录日志


@Component
@Aspect
public class ServiceLogAspect {
    public static final Logger logger = LoggerFactory.getLogger(ServiceLogAspect.class);
    //(*[返回类型] com.duan.nowcoder.community.service[包名].*[类].*[方法](..[参数]))
    @Pointcut("execution(* com.duan.nowcoder.community.service.*.*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before(JoinPoint joinPoint) {
        //获得request实例
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        //获取ip
        String ip = request.getRemoteHost();
        //获取当前时间
        String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
        //获得方法路径及方法名
        String target = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
        // 用户[ip],在[时间],访问了[com.nowcoder.community.service.xxx()].
        logger.info(String.format("用户[%s],在[%s],访问了[%s].", ip, date, target));
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值