Spring In Action--02(详解AOP,AOP实例,AOP基本原理)

 

目录

 

1.AOP概念理解

2.切点表达式的构成

 3.Spring AOP实例:

 4.Spring AOP的原理:


1.AOP概念理解

   软件开发中散布于应用中多处的功能被称为横切关注点,把这些横切关注点与业务逻辑分离,正是面向切面编程所要关注的问题,AOP是一种编程的范式,类似于面向过程,面向函数编程,面向对象编程一样。另外他解决的是特定的问题而不是所有的问题。

  Spring AOP 构建在动态代理的基础上,因此Spring 对 AOP的支持局限于方法拦截,如果需要方法拦截之外的连接点的拦截功能,那么我们可以利用AspectJ来补充Spring AOP的功能。

 AOP相关注解
        @EnableAspectJAutoProxy
        @Aspect
        @PointCut
        @Before、@Around、@After
        @AfterReturning
        @AfterThrowing

  AOP的初衷是什么?第一个初衷就是消除重复的代码。第二个初衷是将关注点分离:

       

 使用AOP的好处:

 AOP的使用场景:

 

 横切关注点被模块化为特殊的类,这个类就被称为切面

   通知定义了切面是什么以及何时使用,通知包含了需要应用于多个应用对象的横切行为。

   连接点是在应用执行过程中能够插入切面的一个点。,是程序执行过程中能够应用通知的所有点。

   切点的定义会匹配通知所要织人的一个或多个连接点。切点定义了通知被应用的具体位置。

   织入是把切面应用到目标对象并创建新的代理对象的过程。

  最关键的概念就是切点定义了哪些连接点会得到通知。创建切点来定义切面所织入的连接点是AOP框架的基本功能。

2.切点表达式的构成

 切面表达式,切点表达式中主要包含三个部分:通配符,运算符,指示器。

    

     

   重点是execution()

    

   匹配包:

  

  匹配对象:第三个是根据bean的id来匹配的

 

     参数匹配:

 

  注解匹配:

 

 只想拦截抛出异常的方法

 

 3.Spring AOP实例:

     先要找到应用中的连接点,即需要通知的点。

    

   编写切面和切点表达式:

@Aspect
public class Audience {

    //定义命名的切点
    @Pointcut("execution(* *com.wx.springinaction.service.Performance.perform(..))")
    public void performance() {
    }

    @Before("performance()")
    public void silenceCellPhone() {
        System.out.println("看表演之前,观众将收集调成静音");
    }

    @Before("performance()")
    public void takeSeats() {
        System.out.println("观众入席坐好");
    }

    // @After  和 @AfterReturning区别:@After=@AfterReturning+@AfterThrowing
    @AfterReturning("performance()")
    public void applause() {
        System.out.println("演出结束观众鼓掌");
    }

    @AfterThrowing("performance()")
    public void demandRefund() {
        System.out.println("演出失败,观众要求退款!!!");
    }
}

 注入切面的bean

@Configuration
@EnableAspectJAutoProxy //启动AspectJ自动代理
@ComponentScan("com.wx.springinaction.service")
public class PerformanceConfig {
    @Bean
    public Audience audience() {
        return new Audience();
    }
}

测试:

下面继续展示环绕通知的用法:

    @Around("performance()")
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        try {
            System.out.println("看表演之前,观众将收集调成静音");
            System.out.println("观众入席坐好");
            proceedingJoinPoint.proceed();
            System.out.println("演出结束观众鼓掌 !!");
        }catch (Throwable e){
            System.out.println("演出失败,观众要求退款!!!");
        }
    }

下面继续展示处理通知中的参数:

连接点变成:

切点变成:

切面变成:

测试:

继续演示通过注解引入新的功能,如果一个切面能够为一个方法增加新的功能,为什么能为一个对象增加新的功能呢?利用引入的AOP概念,切面可以为Spring Bean增加新的方法。特别是没有源码控制权的时候。

要引入表演类的新方法:

新写一个切面:加号表示接口下的所有实现。以及引入接口方法的

配置注入Bean

使用

结果:

Spring AOP的演示到此为止,如果要更加强大的AOP,支持更多的类型那就需要AspectJ,例如当我们创建对象时候可以增加构造器通知,对象属性的改变也可以通知等等众多的类型。

 4.Spring AOP的原理:

  用到的设计模式两种:代理模式,责任链模式,动态代理。

  首先是织入的时机,对于Spring来讲,AOP织入的时机是运行期。

  

代理:

动态代理:java基础--19动态代理

代理的方式有两种,JDK和CGLib,那么Spring AOP 选择的是什么代理方式呢?

Spring 是如何创建出代理的bean呢?

  如何强制使用CGlib的代理:

 然后我们再回答一个问题,多个AOP调用时如何叠加在一起的,答案是采用了责任链的模式

 在Spring 启动的时候,运行期,Spring就会扫描到带有@Aspect注解的切面类,然后根据切点的表达式匹配出所有的连接点,然后会判断这个目标对象是接口实现还是继承实现,然后就可以确定使用JDK还是CGLib的代理方式生成代理类。顺便会判断通知的类型,最后调用的时候当然就是调用代理类啦。

发布了217 篇原创文章 · 获赞 70 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/weixin_37650458/article/details/104080825