原来AOP,才是真爱

                                                         面试遇梗

一次面试,面试官问:“你能说说什么是AOP吗?”

“AOP就是面向切面编程”,然后没有了,好简短的描述,自己都觉得少。如果面向对象是纵向的,那么面向切面就是横向的,心里想着切豆腐的模样,可是并没有说出,自己对AOP的理解还存在理论上,不敢多说,言多必失呀。

“AOP都能做些什么?”,面试官的目光带着些期盼,希望能够回答得多一些。

“记录日志呀”,还是,还是那么一句话。这一句话也是道听途说的,用AOP来做日志,Spring的书看过了好几遍,也没有记住什么精华,到底是用的少。天天写代码,都写的什么玩意,没长脑子就写了吧,自己也忍不住骂了自己几句。

越回答越精简,面试官都不知再如何开口问起,比挤牙膏难多了。面试就这样在尴尬中戛然而止。别人面试都那么久,自己面试保证是最快的一个,半个小时都没有,哎。

                                                             反  思

翻翻资料,Spring框架发展至今也有六七个年头了,作为Spring的两大特性之一,AOP面向切面编程思想,为什么一直是个亮点,为什么会引起那么多开发人员的狂爱呢。

最近在使用SpringCloud框架,想做个日志,什么样的日志呢,就是对用户的一举一动做日志,某年某月某某某做了某某操作,当然,这个可不能对用户说,这些是为后期大数据统计用的。想想以前做项目,要么没有日志,要么是在业务逻辑里手动加log,那么多处理业务逻辑的类,加起来那个辛苦、那个痛苦,回忆起来,老泪纵横呀。

为了避免这个痛苦,一定要痛改前非,狠下心来,静静地研究AOP,有什么难的呢,别人能用的,自己也能用。不用则以,一用不得了,啊,啊,啊,果真是真爱。

                                                          一用钟情

先分析一下,自己的需求,需要在每个Controller层,增加一次注解,用来做日志,然后在每个方法调用时,产生日志。是的,需求就是这么简单,已经拆解过了,只需三步。第一步,需要一个添加日志的注解;第二步,往需要的方法上增加注解;第三步,监控每个方法,通过注解获取方法,并生成日志记录到数据库保存。

第一步,注解类定义

import java.lang.annotation.Documented;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* 日志注解类

* @author 程就人生

* Target 目标为方法

*

*

*/

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface LogAnnotation {

// 请求名称

String controllerName() default “”;

// 模块名称

String module() default “”;

// 请求方式 GET、POST、PUT、DELETE

String actionType() default “”;

}

第二步,执行方法上增加注解

import org.springframework.http.HttpHeaders;

import org.springframework.http.HttpStatus;

import org.springframework.http.ResponseEntity;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PathVariable;

import org.springframework.web.bind.annotation.RestController;

import com.example.demo.annotation.LogAnnotation;

/**

* 测试类

* @author 程就人生

*

*/

@RestController

public class TestController {

@GetMapping(“/test/{id}”)

@LogAnnotation(controllerName=”测试Controller”, module=”测试模块”, actionType=”GET”)

public ResponseEntity<String> test(@PathVariable int id){

String str = “Hello world~!”;

//定义头部消息

HttpHeaders headers = new HttpHeaders();

if(id !=1 ){

throw new RuntimeException(“aaaaaa”);

}else{

headers.add(“success”, “true”);

}

//返回到前端

return new ResponseEntity<>(str, headers, HttpStatus.OK);

}

}

第三步,监控方法类

/**

* Log注入,记录日志

* @author 程就人生

*

*/

@Aspect

@Component

public class LogAop {

    /** * 连接点拦截 * @param joinPoint */

    @Before(“execution(* com.example.demo.controller..*(..))”)

    public void setLog(JoinPoint joinPoint) {

    //获取当前登录用户

    HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();

    User user = (User) request.getSession().getAttribute(“user”);

    //获取被执行的方法

    MethodSignature signature = (MethodSignature) joinPoint.getSignature();

        Method method = signature.getMethod();

        //获取注解中的名称

        LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);

    if(logAnnotation!=null){

    //记录日志

    System.out.println(“请求模块” + logAnnotation.module());

    System.out.println(“Controller名称:” + logAnnotation.controllerName());

    System.out.println(“请求类型:” + logAnnotation.actionType());

    //用户信息

    if(user != null){

    //System.out.println(user.getUserName());

    } 

    }   

    }

}

最后执行以下http://localhost:8701/test/1,可以看到控制台有输出:

《原来AOP,才是真爱》

AOP注入输出

今天,终于可以用AOP面向切面编程的思想来做日志记录了,内心里窃喜,忍不住雀跃了一下,AOP太好用了,AOP,爱死你了。

    原文作者:程就人生
    原文地址: https://www.jianshu.com/p/bc8ce857080b
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞