学习SSM的记录(三)-- Spring Framework--AOP

目录

SpringAOP 面向切面编程

代理

AOP(面向切面编程)

AOP的8个核心名词

SpringAOP基于注解方式实现和细节

SpringAOP底层技术组成:

Spring使用SpringAOP框架的步骤:

演示操作

获取切点详细信息

切点表达式语法

切点表达式的提取和复用

切面优先级


  • SSM为SpringFramework + SpringMVC + MyBatis
  • Spring的3大特性:IoC(控制反转),DI(依赖注入),AOP(面向切面编程)。
  • 框架 = jar + 配置文件

SpringAOP 面向切面编程

代理

代理:将非核心逻辑剥离出来,封装这些非核心逻辑的类,对象,方法。

代理有两种具体实现方式:静态代理和动态代理技术(重点)

  • 静态代理:主动创建代理类(如:要代理Calculate类需要手动创建一个CalculateProxy代理类)
  • 动态代理:
    • JDK动态代理:被代理的类必须实现接口,会根据该接口生成一个代理对象。目标类与代理类的关系只是继承与同一个接口。即A有接口B,JDK代理方式会生成一个有接口B的C为A的代理类。
    • cglib:通过继承被代理的类实现代理,无需实现接口。代理类是目标类的子类,即会直接根据A生成子类B为A的代理类。

Spring AOP框架实际上就是对动态代理的简化

AOP(面向切面编程)

AOP是对OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP可以定义纵向的关系,但不适合定义横向的关系(如:日志功能,日志往往需要横向的分布在所有的对象层次,但OOP无法在对象中实现局部修改,即在对象中的核心方法前后加上日志代码),而AOP能够很好的完善OOP。

AOP思维主要应用场景:

  • 日志记录:在方法前后记录日志
  • 事务处理:在方法前开启事务,在方法后提交或回滚事务
  • 安全控制:在方法前检查权限
  • 性能监控:在方法前后分别记录时间戳,计算执行时间
  • 异常处理:在方法执行时如果出现异常,进行异常处理(记录日志,发送邮件…)
  • 缓存控制:在方法执行前检查缓存中有无数据,有则返回数据,没有则执行方法并将方法返回值存入缓存
  • 动态代理:代理某个类的使用方法,实现各种功能

AOP的8个核心名词

1.横切关注点:AOP把软件系统分为:核心关注点和横切关注点。核心关注点就是业务处理的主要流程;横切关注点经常发送在核心关注点的多处,而且十分相似。

2.通知(增强):提取的重复代码存于一个方法,就是通知方法。

通知一般分为以下几个部分:

  • 前置通知:在目标方法前执行
  • 返回通知:在目标方法成功结束后执行
  • 异常通知:在目标方法异常结束后执行
  • 后置通知:在目标方法最终结束后执行
  • 环绕通知:使用try_catch_finally结构围绕目标方法即以上四种通知。

3.连接点(joinpoint):能被横切的方法都叫连接点,这是一个纯逻辑概念。

4.切点(pointcut):真正被横切的方法就叫做切点。

5.切面(aspect):切点和增强形成一个切面。

6.目标(target):要代理的对象。

7.代理(proxy):生成的代理对象。

8.织入(weave):把通知应用到目标上的行为。

SpringAOP基于注解方式实现和细节

SpringAOP底层技术组成:

  • 动态代理/cglib:会判断目标类是否有接口来生成对应的代理类
  • AspectJ:早期的AOP实现的框架,SpringAOP借用了AspectJ的AOP注解
  • 动态代理是JDK原生的,不需要导包;
  • cglib已经加入spring ioc环境下,只要有springioc需要的包就可以使用;
  • SpringAOP需要spring-aop包,但已经被spring-context进行了依赖传递,所以也不需要导包;
  • AspectJ需要aspectj包,而Spring和AspectJ框架的整合需要spring-aspects包。但spring-aspects包含aspectj包;
  • 所以如果已经导入了spring-context,就只需要到spring-aspectj;如果没有就需要spring-aspects和spring-aop。

Spring使用SpringAOP框架的步骤:

  • 1.导入依赖:
    • ioc/di:spring-context
    • aop:spring-aopaspectj,spring-aspects
    • 测试环境:spring-test
  • 2.编写核心业务并加入ioc容器(要使用SpringAOP的类需要加入到ioc容器中)
  • 3.编写ioc的配置类或配置文件
  • 4.设置测试环境
  • 5.编写增强类,定义增强方法(存储横切关注点的代码)
  • 6.增强类的配置(插入切点的位置,切点指定,切点配置等)
  • 7.开启aop的配置

演示操作

1.导入依赖

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>6.0.6</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-test</artifactId>
    <version>6.0.6</version>
    <scope>test</scope>
</dependency>

2.编写核心业务并加入ioc容器

public interface Calculator {
    int add(int a,int b);
    int sub(int a,int b);
    int mul(int a,int b);
    int div(int a,int b);
}
@Component
public class CalcalatorImpl implements Calculator {
    @Override
    public int add(int a, int b) {
        return a+b;
    }
    @Override
    public int sub(int a, int b) {
        return a-b;
    }
    @Override
    public int mul(int a, int b) {
        return a*b;
    }
    @Override
    public int div(int a, int b) {
        return a/b;
    }
}

3.编写ioc的配置类或配置文件

@Configuration
@ComponentScan("com.qiu.service")
public class JavaConfig {
}

4.设置测试环境

@SpringJUnitConfig(value = JavaConfig.class)
public class SpringAOPTest {
    @Autowired
    private Calculator calculator;
    @Test
    public void test(){
        int add = calculator.add(1, 1);
        System.out.println("add = " + add);
    }
}

5.编写增强类,定义增强方法

public class LogAdvice {
    public void start(){
        System.out.println("方法开始");
    }

    public void after(){
        System.out.println("方法结束");
    }

    public void error(){
        System.out.println("方法报错");
    }
}

6.增强类的配置

@Aspect
@Component
public class LogAdvice {
    @Before("execution(* com.qiu.service.impl.*.*(..))")
    public void start(){
        System.out.println("方法开始");
    }
    @After("execution(* com.qiu.service.impl.*.*(..))")
    public void after(){
        System.out.println("方法结束");
    }
    @AfterThrowing("execution(* com.qiu.service.impl.*.*(..))")
    public void error(){
        System.out.println("方法报错");
    }
}

7.开启aop的配置

@Configuration
@EnableAspectJAutoProxy     //使用aop注解时需要添加
@ComponentScan("com.qiu.service")
public class JavaConfig {
}

其中 add=2 是测试代码中输出的。

获取切点详细信息

  • 获取目标方法的信息(方法名,参数,访问修饰符…):在任何增强方法的形参中加入JoinPoint,如:public void start(JoinPoint joinPoint){…}
  • 获取目标方法返回的结果:
    • 使用@AfterReturning
    • 在形参中添加(Object result)
    • 设置@AfterReturning中的returning  = "result",需要与上方添加的形参的参数名一致
  • 获取目标方法异常的信息:
    • 使用@AfterThrowing
    • 在形参中添加(Throwable t)
    • 设置@AfterThrowing中的throwing= "t",需要与上方添加的形参的参数名一致

切点表达式语法

即之前出现过的"execution(* com.qiu.service.impl.*.*(..))",aop注解通过该表达式来寻找切点

  • 固定语法:execution(1 2 3.4.5(6))    示例:"execution(* com.qiu.service.impl.*.*(..))"
    • 1.访问修饰符:public / private
    • 2.方法的返回参数类型:String int void
    • 如果不考虑1和2,两者可以合并为一个*
    • 3.包的位置:
      • 具体包:com.qiu.service.impl
      • 单层模糊:com.qiu.service.*     * 单层模糊
      • 多层模糊:com..impl                 .. 多层模糊
      • .. 不能开头
    • 4.类的名称
      • 具体:CalculatorImpl
      • 模糊:*
      • 部分模糊:*Impl
    • 5.方法名:与类名一致
    • 6.(6)形参列表
      • ():没有参数
      • (String),(String,int):有具体类型
      • (..):模糊参数,一个或多个
      • (String..),(..int),(String..int):部分模糊,第一个为String;最后为int;第一个为String且最后为int。

切点表达式的提取和复用

1.编写方法来提取复用

@Pointcut("execution(* com.qiu.service.impl.*.*(..))")
public void pc(){}

@Before("pc()")
public void start(JoinPoint joinPoint){
    System.out.println("方法开始");
}

2.创建类来单独维护(记得在配置类中设置ComponentScan扫描这个类)

@Component  //要加到ioc容器中
public class MyPointCut {
    @Pointcut("execution(* com.qiu.service.impl.*.*(..))")
    public void pc(){}
}

@Before("com.qiu.MyPointCut.pc()")
public void start(JoinPoint joinPoint){
    System.out.println("方法开始");
}

切面优先级

如果有多个增强类可以使用@Order()来决定顺序

@Order(值),当值越小时,优先级越高,在越外面

  • 26
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: SpringAOP(面向切面编程)是通过动态代理技术实现的。在运行期间,Spring通过动态地生成代理对象,在代理对象方法执行时进行增强功能的介入,然后再调用目标对象的方法,从而实现功能增强。\[2\]在使用SpringAOP时,需要导入相关的JAR包。例如,可以通过在项目的pom.xml文件中添加依赖来导入SpringAOP相关的JAR包,如下所示:\[1\] ``` <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.0.5.RELEASE</version> <scope>compile</scope> </dependency> ``` 此外,还需要导入AspectJ框架相关的JAR包,如spring-aspects和aspectjweaver。\[3\]在项目中使用AOP时,可以通过创建接口和在接口中定义需要增强的方法来实现AOP的功能。例如,在com.ssm.aspectj包中创建一个UserDao接口,并在接口中定义添加用户和删除用户的方法。\[3\] #### 引用[.reference_title] - *1* *2* [SpringAOP介绍和使用](https://blog.csdn.net/weixin_60719453/article/details/126262103)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [Spring中的AOP](https://blog.csdn.net/m0_46741750/article/details/118513316)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值