简单理解Spring Aop

一、什么是AOP

AOP是一种思想,也称为“面向切面编程”。

AOP 技术利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类
的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,
就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的
重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

AOP将程序中业务处理的主要逻辑称为“核心关注点”,其他次要的部分称为“横切关注点”。横切关注点的特点是,它们经常发生在核心关注点的多处,且各处基本相似。比如权限认证、日志等。Aop 的作用在于抽离出系统中的横切关注点,以降低模块间的耦合度。

二、AOP的原理

AOP是基于代理(Proxy)实现的,具体实现方式有两种:

  • jdk动态代理
    – 若目标对象有实现接口,用JDK代理
  • Cglib代理
    –若目标对象没有实现接口,默认用Cglib代理

ps:(对于这两种代理有兴趣的同学可以看下这篇文章) https://www.cnblogs.com/cenyu/p/6289209.html

三、AOP中的基本概念

AOP中的基本概念很多很杂,这里简要介绍几种,

  • 通知(Adivce):
    通知有"Before,After ,After-returning,After-throwing,Around" 五种类型

  • 切面(Aspect):
    切面是切点和通知的集合,一般单独作为一个类。

  • 连接点(Join point):
    程序执行的某个特定位置(如:某个方法调用前、调用后,方法抛出异常后),一个类或一段程序代码拥有一些具有边界性质的特定点,这些代码中的特定点就是连接点。Spring仅支持方法的连接点。

  • 切点(Pointcut):
    如果连接点相当于数据中的记录,那么切点相当于查询条件,一个切点可以匹配多个连接点

四、一个简单的AOP例子

前面说过,aop的作用就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度。现在比如说有一个web项目,我们需要知道一个方法的执行时间并且打印日志,那么此时我们可以利用aop来实现。
首先用IntelliJ IDEA 创建一个springboot项目叫做aopdemo,然后在aopdemo下新建两个程序:
在这里插入图片描述

@Controller
public class HelloController {
    private static final Logger logger = LoggerFactory.getLogger(HelloController.class);

    @RequestMapping(path = {"/hello"})
    @ResponseBody
    public String Hello(){
        logger.info("Hello World");
        try {
            Thread.sleep(3000);//这里让线程睡眠3s,以便在后面辨别方法执行前后的时间
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "Hello World";
    }
}

由于刚创建的项目没有AOP相关的依赖,所以要在pom.xml文件中加入:

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
 </dependency>
@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    // execution即执行,*是通配符,以下语句的作用就是匹配com.example.aopdemo.controller包
    // 中HelloController类的所有方法,也就是说当HelloController类中的任意方法被调用时,
    // 此方法会在其之前先调用
    @Before("execution(* com.example.aopdemo.controller.HelloController.*(..))")
    public void beforeMethod(JoinPoint joinPoint){
        logger.info("before method:"+ df.format(new Date()));
    }

    @After("execution(* com.example.aopdemo.controller.HelloController.*(..))")
    public void afterMethod(JoinPoint joinPoint){
        logger.info("after method:"+ df.format(new Date()));
    }
}

运行AopdemoApplication,在浏览器中输入“http://localhost:8080/hello”
在这里插入图片描述
可以看到控制台打印出的log如下:
在这里插入图片描述
当HelloController 的hello方法被执行前,aop先执行了beforeMethod方法,hello方法执行完之后,再执行了afterMethod方法,由于hello方法睡眠了3s,所以打印出来执行前后的时间差也是3s,符合我们的预期。

这只是aop的一个简单应用,更多更复杂的还需要我们一点点去了解。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值