Spring AOP入门

综合技术 2018-06-24 阅读原文

Spring的核心有两部分,IOC和AOP,那么AOP的重要性可想而知,今天一块来了解下Spring AOP相关的内容。

AOP概念

AOP(Aspect-Oriented Programming)是面向切面编程的简称,定义如下:

计算机科学中,AOP是一种编程范式,通过分离横切关注点点来增加模块性。它可以在已有的代码上增加额外的行为,却不需要修改已有的代码,而是通过指定代码的切点来实现。

In computing, aspect-oriented programming (AOP) is a programming paradigm that aims to increase modularity by allowing the separation of cross-cutting concerns. It does so by adding additional behavior to existing code (an advice) without modifying the code itself, instead separately specifying which code is modified via a "pointcut" specification

个人对这个概念的理解,如果仅仅使用OOP编程,虽然对象与对象有相互交错的地方,但大部分时候我们要遵循“单一职责”原则,即每个类只做一件事,做好自己的事情,这样很多类都是只做自己的事,类之间不相互知悉,但实际上它们之间有一些共同的事情要做。比如日志,事务,认证操作。

虽然通过OOP的设计模式也可以实现复用效果,但AOP更加直观容易操作,OOP本身还是在代码中比AOP耦合的更多,AOP基本不需要侵入修改原本的代码。

如图:

image.png

AOP 术语

image.png

  • JoinPoint(连接点,加入点),如类的初始化前,类的初始化后,类的某个方法调用前,类的某个方法调用后,方法抛出异常后等位置。 Spring仅支持方法的JoinPoint
  • PointCut(切点),每个程序都有多个JoinPoint, 其中我们感兴趣的那个JoinPoint,要下手操作的那个点叫做Pointcut。
  • Advice(增强),我们找到感兴趣的点(PointCut)之后做什么呢,不管做什么,都是比之前做的事情多了那么一点点,所以可以理解为增强。
  • Target 目标对象,要下手的目标类
  • Weaving (织入),将Advice添加到Target的具体JoinPoint的过程。

AOP案例

先看一个案例,然后根据案例来进行思考。

需要对Spring的Ioc及Bean的概念有些了解。

  1. 新建一个Maven项目,依赖如下
        
            org.springframework
            spring-aop
            4.3.14.RELEASE
        
        
            org.springframework
            spring-context
            4.3.14.RELEASE
        
        
            org.aspectj
            aspectjweaver
            1.8.11
        
        
            commons-logging
            commons-logging
            1.2
        
    
  1. 新建测试类HelloWorld,
public class HelloWorld {
    public void sayHello(){
        System.out.println("hello");
    }
}
  1. 新建在切点上的操作,上面提到了AOP是对某些通用的东西做一些操作,操作被称为Advice
/**
* 记录方法的执行时间
*/
public class TimeLoggingAop implements MethodBeforeAdvice,AfterReturningAdvice {
    private long startTime = 0;

    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        startTime = System.nanoTime();

    }

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] objects, Object target) throws Throwable {
        long spentTime = System.nanoTime() - startTime;
        String clazzName = target.getClass().getCanonicalName();
        String methodName = method.getName();
        System.out.println("执行" + clazzName + "#" + methodName + "消耗" + new BigDecimal(spentTime).divide(new BigDecimal(1000000)) + "毫秒");
    }
}
  1. resouce目录下新建Spring配置文件


    
    
    
        
        
    
  1. 创建App类
public class App {
    public static void main(String[] args) {
        // 加载Spring配置文件
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
        HelloWorld helloWorld = applicationContext.getBean(HelloWorld.class);
        helloWorld.sayHello();

    }
}
  1. 运行结果
hello
执行com.qiandao.mall.controller.HelloWorld#sayHello消耗33.337513毫秒

案例分析

我们的HelloWorld类功能只是打印Hello,最后在打印Hello之后,又打印了这个方法的执行时间。

其中:

  • HelloWorld为目标对象
  • TimeLogAOP实现了BeforeAdvice,AfterReturningAdvice 是 Advice
  • Pointcut为HelloWorld的方法执行前与方法返回值后,两个切点
  • 织入过程为Spring内部实现

最后

本次我们解释了AOP的概念和AOP相关的术语,并通过一个案例来说明具体术语的含义,希望能帮到大家。

简书

责编内容by:简书阅读原文】。感谢您的支持!

您可能感兴趣的

详解设计模式在Spring中的应用 1. 简单工厂 又叫做静态工厂方法(StaticFactory Method)模式,但不属于23种GOF设计模式之一。 简单工厂模式的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类。 Spring中的BeanFactory就是简单工厂模式的体现,根据传入一个唯一的标识来获得...
Spring @Value TypeMismatchException&... I want to use the @Value annotation to inject a Double property such as: @Service public class MyService {@Value("${item.priceFactor}") pr...
WebSocket的故事(四)—— Spingboot中,如何利用WebSocket和STOMP快速... 最近事情太多,也有好久没有更新了。在此感谢大家的持续关注。如果有任何问题,都可以私信我一起讨论。 概述 本文是 WebSocket的故事 系列第三篇第二节,将针对上篇的代码介绍,给出一个STOMP实现点对点消息的简单例子。WebSocket的故事系列计划分六大篇,旨在由浅入深的介绍WebS...
Running Spring Tool Suite and other GUI applicatio... Running an application within a Docker container helps in isolating the application from the host OS. Running GUI applications like for example an ID...
Spring源码解析:循环依赖的探测与处理... Spring 为开发人员提供了极其灵活和强大的配置方式,在方便使用的同时也为容器的初始化过程带来了不确定性,本篇所要介绍的循环依赖就是其中之一,尤其在一些大型项目中,循环依赖的配置往往是我们不经意而为之的,幸好 Spring 能够在初始化的过程中探测到对象之间的循环依赖,并能够在一定程度上对其进行处...