spring框架-认识AOP(三)

简介: spring框架-认识AOP(三)

回顾:

spring框架-认识spring框架(一)


spring框架-认识IOC(二)


目录


AOP综述


AOP是什么


AOP有什么用


AOP怎么用


AOP优点


探索AOP


AOP原理


AOP的动态代理:


JDK代理和CGLib代理我们该用哪个


AOP术语


连接点(JointPoint)


切入点(PointCut)


增强/通知(Advice)


前置通知(MethodBeforeAdvice )


后置通知 (AfterReturningAdvice )


环绕通知(MethodInterceptor)


异常通知(ThrowsAdvice)


引介通知(IntroductionInterceptor)


切面(Aspect)


织入(weaving)


目标对象(target)


顾问(Advisor)


Spring对AOP的支持


知识点


切面类型主要分成了三种


使用引介/引入功能实现为Bean引入新方法


总结


AOP综述

AOP是什么

Aspect-oriented programming 面向切面(方面)编程


AOP有什么用

可以把业务逻辑和系统级的服务进行隔离

系统级的服务像系统的日志,事务,权限验证等


AOP怎么用

动态代理


AOP优点

1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦

2、低侵入式设计,代码的污染极低

3、利用它很容易实现如权限拦截,运行期监控和系统日志等功能


探索AOP

如果没有接触过AOP(面向切面编程)的,可能一时间没办法理解,因为之前都是用JAVA的面向对象编程(OOP),没关系,一步步跟我来学习AOP。


当然如果您是技术大牛,既然您抽出时间查看了虚竹的文章,欢迎纠正文章中的不足和缺陷

我们先来看下来这段《精通Spring4.x 企业应用开发实战》提供的代码片段image.png图上的业务代码被事务管理代码和性能监控代码所包围,而且学过JAVA的都知道,出现重复代码了。出现重复代码那就需要重构代码,代码的重构步骤一般有这两种:


1、抽成方法


2、抽成类


抽取成类的方式我们称之为:纵向抽取


通过继承的方式实现纵向抽取

但是,虚竹发现这种抽取方式在图上的业务中不适用了,因为事务管理代码和性能监控代码是跟对应的业务代码是有逻辑关系的

image.pngAOP原理

AOP的底层原理就是动态代理(如果没听过代理模式,可以看看这位大神写的博客给女朋友讲解什么是代理模式)


来源《Spring 实战 (第4版)》一句话:

     Spring AOP构建在动态代理基础之上,因此,Spring对AOP的支持局限于方法拦截。


AOP的动态代理:

jdk动态代理

cglib动态代理

Spring在选择用JDK动态代理还是CGLiB动态代理的依据:


  (1)当Bean实现接口时,Spring就会用JDK的动态代理


  (2)当Bean没有实现接口时,Spring使用CGlib是实现


(3)可以强制使用CGlib(在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)


JDK代理和CGLib代理我们该用哪个

在《精通Spring4.x 企业应用开发实战》给出了建议:


   如果是单例的我们最好使用CGLib代理,如果是多例的我们最好使用JDK代理


原因:


   JDK在创建代理对象时的性能要高于CGLib代理,而生成代理对象的运行性能却比CGLib的低。

   如果是单例的代理,推荐使用CGLib


现在大家知道什么是AOP了吧:把非业务重复代码横向抽取出来,通过动态代理织入目标业务对象函数中,实现跟之前一样的代码


AOP术语

aop术语不好理解,《精通Spring4.x 企业应用开发实战》书上有提到这些术语,我尽量解释下这些术语


连接点(JointPoint)

一个类中的所有方法都可以被称为连接点


切入点(PointCut)

上面也说了,每个方法都可以称之为连接点,我们具体定位到某一个方法就成为切点。


用注解来说明,被@Log定义的方法就是切入点image.png增强/通知(Advice)

表示添加到切点的一段逻辑代码,并定位连接点的方位信息。


前置通知(MethodBeforeAdvice )

前置通知是在目标方法执行前执行


后置通知 (AfterReturningAdvice )

后置通知是在目标方法执行后才执行 ,可以得到目标方法返回的值 ,但不能改变返回值


环绕通知(MethodInterceptor)

环绕通知有在目标方法执行前的代码,也有在目标方法执行后的代码,可以得到目标方法的值,可以改变这个返回值!

扩展知识点:

spring中的拦截器分两种:

1、HandlerInterceptor

2、MethodInterceptor

HandlerInterceptor是springMVC项目中的拦截器,它拦截的目标是请求的地址,比MethodInterceptor先执行

MethodInterceptor是AOP项目中的拦截器,它拦截的目标是方法,即使不是controller中的方法。


异常通知(ThrowsAdvice)

最适合的场景就是事务管理


引介通知(IntroductionInterceptor)

引介通知比较特殊,上面的四种通知都是在目标方法上织入通知,引介通知是在目标类添加新方法或属性


简单来说就定义了是干什么的,具体是在哪干

Spring AOP提供了5种Advice类型给我们:前置通知、后置通知、返回通知、异常通知、环绕通知给我们使用!

切面(Aspect)

切面由切入点和增强/通知组成


交叉在各个业务逻辑中的系统服务,类似于安全验证,事务处理,日志记录都可以理解为切面


织入(weaving)

就是将切面代码插入到目标对象某个方法的过程,相当于我们在jdk动态代理里面的 invocationHandler接口方法的内容


用注解解释:就是在目标对象某个方法上,打上切面注解


目标对象(target)

切入点和连接点所属的类


顾问(Advisor)

就是通知的一个封装和延伸,可以将通知以更为复杂的方式织入到某些方法中,是将通知包装为更复杂切面的装配器。


Spring对AOP的支持

Spring提供了3种类型的AOP支持:


基于代理的经典SpringAOP

需要实现接口,手动创建代理

纯POJO切面

使用XML配置,aop命名空间

@AspectJ注解驱动的切面

使用注解的方式,这是最简洁和最方便的!

知识点

切面类型主要分成了三种

一般切面

切点切面

引介/引入切面

image.png

一般切面,切点切面,引介/引入切面说明:

image.png引介/引入切面有两个实现类:


DefaultIntroductionAdvisor:常用的实现类

DeclareParentsAdvisor:用于实现AspectJ语言的DeclareParent注解表示的引介/引入切面

实际上,我们使用AOP往往是Spring内部使用BeanPostProcessor帮我们创建代理。


这些代理的创建器可以分成三类:


基于Bean配置名规则的自动代理创建器:BeanNameAutoProxyCreator

基于Advisor匹配机制的自动代理创建器:它会对容器所有的Advisor进行扫描,实现类为DefaultAdvisorAutoProxyCreator

基于Bean中的AspectJ注解标签的自动代理创建器:AnnotationAwareAspectJAutoProxyCreator

对应的类继承图:

image.png

使用引介/引入功能实现为Bean引入新方法

其实前置通知,后置通知,还是环绕通知,这些都很好理解。整个文章就引介/引入切面比较有趣,我们来实现试试吧

有个服务员的接口:image.pngimage.png

public class TestAop {
    @Test
    public void testAop(){
        ApplicationContext ac = new ClassPathXmlApplicationContext("dispatcher-servlet.xml","applicationContext-datasource.xml","applicationContext.xml");
        Waiter waiter = ac.getBean("Waiter",Waiter.class);
        // 调用服务员原有的方法
        waiter.greetTo("虚竹");
        waiter.serveTo("虚竹");
        // 通过引介/引入切面已经将waiter服务员实现了Seller接口,所以可以强制转换
        Seller seller = (Seller) waiter;
        seller.sell("东西", "虚竹");
    }
}

image.png总结

AOP的底层实现是动态代理,动态代理包含JDK动态代理和CGLib代理。当Bean实现接口时,Spring就会用JDK的动态代理;当Bean没有实现接口时,Spring使用CGlib是实现;可以强制使用CGlib。

如果是单实例,推荐使用CGLib代理,如果是多例的我们最好使用JDK代理。因为CGLib代理对象运行速度要比JDK的代理对象要快

AOP的层面是方法级别的,只能对方法进入拦截

无论是XML方式还是注解方式,原理都一样,我们用注解AOP就够了,简单好用

引介/引入切面是比较有趣的,具体实现上面举例说明了,它可以达到用某个接口的方法,又不入侵代码,低耦合的效果。具体妙处还待开发,后面有发现再补充说明

脑图链接:https://www.processon.com/view/link/5c51671be4b048f108e2aa0f


查看链接可以看到更多信息,脑图的备注没办法导成图片image.png


image.png

目录
相关文章
|
3天前
|
Java 数据安全/隐私保护 Spring
Java 中 Spring Boot 框架下的 Email 开发
Java 中 Spring Boot 框架下的 Email 开发
29 2
|
3天前
|
缓存 前端开发 Java
【框架】Spring 框架重点解析
【框架】Spring 框架重点解析
18 0
|
3天前
|
XML Java 数据格式
Spring框架入门:IoC与DI
【5月更文挑战第15天】本文介绍了Spring框架的核心特性——IoC(控制反转)和DI(依赖注入)。IoC通过将对象的创建和依赖关系管理交给容器,实现解耦。DI作为IoC的实现方式,允许外部注入依赖对象。文章讨论了过度依赖容器、配置复杂度等常见问题,并提出通过合理划分配置、使用注解简化管理等解决策略。同时,提醒开发者注意过度依赖注入和循环依赖,建议适度使用构造器注入和避免循环引用。通过代码示例展示了注解实现DI和配置类的使用。掌握IoC和DI能提升应用的灵活性和可维护性,实践中的反思和优化至关重要。
17 4
|
3天前
|
XML 监控 安全
Spring特性之一——AOP面向切面编程
Spring特性之一——AOP面向切面编程
15 1
|
3天前
|
安全 Java Spring
Spring框架中的单例Bean是线程安全的吗?
Spring框架中的单例Bean是线程安全的吗?
10 1
|
1天前
|
前端开发 Java 关系型数据库
使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC
使用IDEA搭建一个Spring + AOP (权限管理 ) + Spring MVC
|
3天前
|
JSON 前端开发 Java
【JavaEE】Spring全家桶实现AOP-统一处理
【JavaEE】Spring全家桶实现AOP-统一处理
5 0
|
3天前
|
前端开发 Java 开发者
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
【JavaEE】面向切面编程AOP是什么-Spring AOP框架的基本使用
10 0
|
3天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(下)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
6 0
|
3天前
|
JSON 前端开发 Java
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解(上)
【JavaEE】让“单车变摩托”的神级框架—Spring MVC的深入讲解
5 0