SSM——Spring面向切面编程AOP

一. Spring 的 AOP 简介

1. 什么是 AOP

  • AOP 为 Aspect Oriented Programming 的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
  • AOP 是 OOP 的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

2. AOP 的作用及其优势

  • 作用:在程序运行期间,在不修改源码的情况下对方法进行功能增强
  • 优势:减少重复代码,提高开发效率,并且便于维护

在这里插入图片描述

3. AOP 的底层实现

  • 实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。

在这里插入图片描述

3.1 JDK 的动态代理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

3.2 cglib 的动态代理

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

package com.itheima.proxy.cglib;

import com.itheima.proxy.jdk.TargetInterface;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyTest {

    public static void main(String[] args) {

        //目标对象
        final Target target = new Target();

        //增强对象
        final Advice advice = new Advice();

        //返回值 就是动态生成的代理对象  基于cglib
        //1、创建增强器
        Enhancer enhancer = new Enhancer();
        //2、设置父类(目标)
        enhancer.setSuperclass(Target.class);
        //3、设置回调
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                advice.before(); //执行前置
                Object invoke = method.invoke(target, args);//执行目标
                advice.afterReturning(); //执行后置
                return invoke;
            }
        });
        //4、创建代理对象
        Target proxy = (Target) enhancer.create();


        proxy.save();


    }

}

在这里插入图片描述

4. AOP 相关概念

在这里插入图片描述

5. AOP 开发明确的事项

在这里插入图片描述

二. 基于 XML 的 AOP 开发

在这里插入图片描述

1. 导入 AOP 相关坐标

<!--导入spring的context坐标,context依赖aop-->
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>5.0.5.RELEASE</version>
</dependency>
<!-- aspectj的织入 -->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.8.13</version>
</dependency>

2. 创建目标接口和目标类(内部有切点)

在这里插入图片描述

在这里插入图片描述

3. 创建切面类(内部有增强方法)

在这里插入图片描述

4. 将目标类和切面类的对象创建权交给 spring

在这里插入图片描述

5. 在 applicationContext.xml 中配置织入关系

在这里插入图片描述
在这里插入图片描述

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
">


    <!--目标对象-->
    <bean id="target" class="com.itheima.aop.Target"></bean>

    <!--切面对象-->
    <bean id="myAspect" class="com.itheima.aop.MyAspect"></bean>

    <!--配置织入:告诉spring框架 哪些方法(切点)需要进行哪些增强(前置、后置...)-->
    <aop:config>
        <!--声明切面-->
        <aop:aspect ref="myAspect">
            <!--抽取切点表达式-->
            <aop:pointcut id="myPointcut" expression="execution(* com.itheima.aop.*.*(..))"></aop:pointcut>
            <!--切面:切点+通知-->
            <!--<aop:before method="before" pointcut="execution(public void com.itheima.aop.Target.save())"/>-->
            <!--<aop:before method="before" pointcut="execution(* com.itheima.aop.*.*(..))"/>
            <aop:after-returning method="afterReturning" pointcut="execution(* com.itheima.aop.*.*(..))"/>-->
            <!--<aop:around method="around" pointcut="execution(* com.itheima.aop.*.*(..))"/>
            <aop:after-throwing method="afterThrowing" pointcut="execution(* com.itheima.aop.*.*(..))"/>
            <aop:after method="after" pointcut="execution(* com.itheima.aop.*.*(..))"/>-->
            <aop:around method="around" pointcut-ref="myPointcut"/>
            <aop:after method="after" pointcut-ref="myPointcut"/>

        </aop:aspect>
    </aop:config>

</beans>

6. 测试代码

在这里插入图片描述
在这里插入图片描述

7. XML 配置 AOP 详解

7.1 切点表达式的写法

在这里插入图片描述

7.2 通知的类型

在这里插入图片描述

7.3 切点表达式的抽取

在这里插入图片描述

三. 基于注解的 AOP 开发

在这里插入图片描述

1. 创建目标接口和目标类(内部有切点)

在这里插入图片描述

2. 创建切面类(内部有增强方法)

在这里插入图片描述

3. 将目标类和切面类的对象创建权交给 spring

在这里插入图片描述
在这里插入图片描述

package com.itheima.anno;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component("myAspect")
@Aspect //标注当前MyAspect是一个切面类
public class MyAspect {

    //配置前置通知
    //@Before("execution(* com.itheima.anno.*.*(..))")
    public void before(){
        System.out.println("前置增强..........");
    }

    public void afterReturning(){
        System.out.println("后置增强..........");
    }

    //Proceeding JoinPoint:  正在执行的连接点===切点
    //@Around("execution(* com.itheima.anno.*.*(..))")
    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("环绕前增强....");
        Object proceed = pjp.proceed();//切点方法
        System.out.println("环绕后增强....");
        return proceed;
    }

    public void afterThrowing(){
        System.out.println("异常抛出增强..........");
    }

    //@After("execution(* com.itheima.anno.*.*(..))")
    @After("MyAspect.pointcut()")
    public void after(){
        System.out.println("最终增强..........");
    }

    //定义切点表达式
    @Pointcut("execution(* com.itheima.anno.*.*(..))")
    public void pointcut(){}

}

4. 在切面类中使用注解配置织入关系

在这里插入图片描述

5. 在配置文件中开启组件扫描和 AOP 的自动代理

在这里插入图片描述
在这里插入图片描述

6. 测试代码

在这里插入图片描述
在这里插入图片描述

7. 注解配置 AOP 详解

7.1 注解通知的类型

在这里插入图片描述

7.2 切点表达式的抽取

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值