【小家Spring】Spring AOP的多种使用方式以及神一样的AspectJ-AOP使用介绍(上)

简介: 【小家Spring】Spring AOP的多种使用方式以及神一样的AspectJ-AOP使用介绍(上)

什么是AOP


AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。


AOP技它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。


实现AOP的技术,主要分为两大类:一是采用动态代理技术(典型代表为Spring AOP),利用截取消息的方式(典型代表为AspectJ-AOP),对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。


相关概念


        切面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。切面用spring的 Advisor或拦截器实现。


        连接点(Joinpoint): 程序执行过程中明确的点,如方法的调用或特定的异常被抛出。


       通知(Advice): 在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。Spring中定义了四个advice: BeforeAdvice, AfterAdvice, ThrowAdvice和DynamicIntroductionAdvice


       切入点(Pointcut): 指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点:例如,使用正则表达式。 Spring定义了Pointcut接口,用来组合MethodMatcher和ClassFilter,可以通过名字很清楚的理解, MethodMatcher是用来检查目标类的方法是否可以被应用此通知,而ClassFilter是用来检查Pointcut是否应该应用到目标类上


        引入(Introduction): 添加方法或字段到被通知的类。 Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现 IsModified接口,来简化缓存。Spring中要使用Introduction, 可有通过DelegatingIntroductionInterceptor来实现通知,通过DefaultIntroductionAdvisor来配置Advice和代理类要实现的接口(使用较少)


      目标对象(Target Object): 包含连接点的对象。也被称作被通知或被代理对象。POJO


      AOP代理(AOP Proxy): AOP框架创建的对象,包含通知。 在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。


       织入(Weaving): 组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。


AOP概念的通俗理解


1.通知(Advice): 通知定义了切面是什么以及何时使用。描述了切面要完成的工作和何时需要执行这个工作。

2.连接点(Joinpoint): 程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法被调用时、异常被抛出时等等。

3.切入点(Pointcut) :通知定义了切面要发生的“故事”和时间,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定

4.切面(Aspect) :通知和切入点共同组成了切面:时间、地点和要发生的“故事”

5.引入(Introduction) :引入允许我们向现有的类添加新的方法和属性(Spring提供了一个方法注入的功能)

6.目标(Target) :即被通知的对象,如果没有AOP,那么它的逻辑将要交叉别的事务逻辑,有了AOP之后它可以只关注自己要做的事(AOP让他做爱做的事)

7.代理(proxy) :应用通知的对象,详细内容参见设计模式里面的代理模式

8.织入(Weaving) :把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:


---- (1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器

---- (2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码

----(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术

Spring AOP的三种实现方式(基于Spring Boot)


一、基于XML配置的Spring AOP


现在都是spring boot的时代了,因此基于xml配置的例子,本文不做介绍了,有需要的可以自己去找其余博文阅读


二、基于ProxyFactoryBean,编码的方式来实现


导包


 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>


有如下包即可正常工作了


image.png


备注:aopalliance.jar这个jar包已经不用单独引入了,因为Spring-AOP包已经把这个jar包内全部的类都已经放进来了(如下图),因此无需重复引入 只需要引入依赖包:org.aspectj:aspectjweaver即可


image.png


为何Spring自己实现了AOP,还需要导入org.aspectj:aspectjweaver的包呢?


官网解释的原因如下:


      原因一:spring确实有自己的AOP。功能已经基本够用了,除非你的要在接口上动态代理或者方法拦截精确到getter和setter。这些都是写奇葩的需求Spring做不到,但一般不使用。


      原因二:1、如果使用xml方式,不需要任何额外的jar包。2、如果使用@Aspect的注解方式。你就可以在类上直接一个@Aspect就搞定,不用费事在xml里配了。但是这需要额外的jar包( aspectjweaver.jar)。因为spring直接使用AspectJ的注解功能,注意只是使用了它 的注解功能而已。并不是核心功能 !!!


注意到文档上还有一句很有意思的话:文档说到 是选择spring AOP还是使用full aspectJ?什么是full aspectJ?如果你使用"full aspectJ"。就是说你可以实现基于接口的动态代理,等等强大的功能。而不仅仅是aspectj的 注-解-功-能 !!!


如果用full AspectJ。比如说Load-Time Weaving的方式 还 需要额外的jar包 spring-instrument.jar。。。现在明白了吧~~~ 具体详情,后面在讲述AspectJ里可以看见~~


基本类如下:

// A类:
@Service
public class AServiceImpl implements AService {
    @Override
    public void sayHelloA() {
        System.out.println("hello A");
    }
}
// B类:
@Service
public class BServiceImpl implements BService {
    @Override
    public void sayHelloB() {
        System.out.println("hello B");
    }
}
// C类:
@Service
public class CServiceImpl implements CService {
    @Override
    public void sayHelloC() {
        System.out.println("hello C");
    }
}

通过实现接口的方式编写的通知类


/**
 * 在方法之前、之后 打印输出日志
 *
 * @author fangshixiang@vipkid.com.cn
 * @description
 * @date 2018-10-29 17:42
 */
@Component //通知组件交给容器管理
public class LogAdvice implements MethodBeforeAdvice, AfterReturningAdvice, MethodInterceptor {
    //MethodBeforeAdvice的方法
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("MethodBeforeAdvice...before...");
    }
    //AfterReturningAdvice的方法
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("AfterReturningAdvice...afterReturning...");
    }
    //MethodInterceptor的方法
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("MethodInterceptor...invoke...start");
        Object proceed = invocation.proceed();
        System.out.println("MethodInterceptor...invoke...end");
        return proceed;
    }
}


实现接口 MethodBeforeAdvice该拦截器会在调用方法前执行

实现接口 AfterReturningAdvice该拦截器会在调用方法后执行

实现接口 MethodInterceptor该拦截器会在调用方法前后都执行,实现环绕效果


然后就是配置了,其中最重要的类为ProxyFactoryBean、BeanNameAutoProxyCreator、AspectJExpressionPointcutAdvisor等等代理类,能达到强大的效果。这种一般都是spring时代基于xml的书写方式,因此这里不做详细讲解,SpringBoot时代,建议使用优雅的注解的风格编写,但本文提供一个参考博文:

Spring AOP之ProxyFactoryBean与BeanNameAutoProxyCreator


相关文章
|
11天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
1月前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
37 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
17天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
13天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
27 0
|
2月前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
1月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
73 2
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
127 9
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
46 0
|
2月前
|
Java 数据库连接 数据库
Spring基础3——AOP,事务管理
AOP简介、入门案例、工作流程、切入点表达式、环绕通知、通知获取参数或返回值或异常、事务管理
Spring基础3——AOP,事务管理
|
3月前
|
Java Spring XML
掌握面向切面编程的秘密武器:Spring AOP 让你的代码优雅转身,横切关注点再也不是难题!
【8月更文挑战第31天】面向切面编程(AOP)通过切面封装横切关注点,如日志记录、事务管理等,使业务逻辑更清晰。Spring AOP提供强大工具,无需在业务代码中硬编码这些功能。本文将深入探讨Spring AOP的概念、工作原理及实际应用,展示如何通过基于注解的配置创建切面,优化代码结构并提高可维护性。通过示例说明如何定义切面类、通知方法及其应用时机,实现方法调用前后的日志记录,展示AOP在分离关注点和添加新功能方面的优势。
54 0