Spring框架的关键组件之Aop配置

本文详细介绍了Spring框架中的AOP关键组件,包括AOP相关概念、注解配置和XML配置方式。讲解了如何使用注解进行AOP配置,如目标对象无接口、目标对象继承接口的情况,以及各种切入点表达式的使用。此外,还对比了Spring AOP与AspectJ的选择考虑因素。
摘要由CSDN通过智能技术生成

1、AOP相关概念的介绍

Spring框架的关键组件之一是AOP框架,虽然Spring IoC容器不依赖于AOP,但在Spring应用中,经常会使用AOP来简化编程。

优势

  • 提供声明式企业服务,可以进行声明式事务管理
  • 允许实现自定义的切面,某些不适用OOP编程的场景中,采用AOP来补充。
  • 可以对业务逻辑的各个部分进行隔离,从而降低业务逻辑之间的耦合度,提高程序的可用性,同时提高了开发的小路。

Spring要使用AOP模块,需要导入spirng-aop模块对应的jar。

AOP核心概念

AOP的概念使用大多数AOP框架,如AspectJSprng AOP

  1. Aspect(切面):将关注点模块化,可以横跨多个对象,例如事务管理。在SpringAOP中,切面可以使用常规类(基于模式的方法)或者使用@Apsect注解的常规类来实现。
  2. Join Point(连接点):在程序执行中抽取出来的特定点,例如方法调用时或处理处理时。Spring AOP中,连接点总是代表一个方法的执行。
  3. Advice(通知):在切面的某个特定的连接点上执行的动作,通知的类型有before、after等通知
  4. Pointcut(切入点):匹配连接点的断言,通知和一个切入点表达式关联。并在满足这个连接的上运行。(切入点表达式和连接点的匹配时AOP的核心)。
  5. Introduction(引入):声明额外的方法或者某个类型库的字段,SpringAOP的使用从允许一个新的接口(加上对应的实现类,使用的是JDK动态代理)到任何被通知的对象(不需要实现接口,普通的Java类,使用的是CGLIB代理)。
  6. Target Object(目标对象):被一个及以上的切面所通知的对象。Spring主要时通过运行代理实现的,所以目标对象来永远是一个Proxied(被代理)对象
  7. AOP Proxy(AOP代理):AOP框架创建的对象,用来实现Apsect Contract(切面契约)包含通知方法执行功能等。
  8. Weaving(织入):把切面连接到对象上,并创建一个Advised对象(代理对象)的过程。可以在编译时(AspectJ编译器)、类加载时和运行时完成(Spring AOP)

支持的通知:

  • Before(前置通知):在连接点之前执行的通知(这个通知不能阻止连接前的执行,除非出异常)
  • AferReturning(返回通知):在方法(连接点)正常执行后,没有异常的时候,就会执行到该方法
  • AfterThrowing(抛出异常通知):在方法抛出异常推出的时候执行的通知
  • After(最后通知):当方法退出时执行的语句,无论是否出现异常,都会执行
  • Around(环绕通知):包围一个连接点的通知,是前面四个通知的总和。

Spriing目前只支持方法调用作为连接点使用,默认使用的JDK动态代理,如果代理类没有实现接口再使用CGLIB代理

2、使用注解配置Spring AOP

Java配置类

package com.example.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration  // 表明该类是配置类
@EnableAspectJAutoProxy // 启用Spring AOP
@ComponentScan("com.example") // 指定扫描的包
public class SpringAopConfig {
   

}

2.1、目标对象没有是接口

目标类

package com.example.aop;

import org.springframework.stereotype.Component;
import java.math.BigDecimal;

@Component
public class GeneralPerson {
   
    public void say(){
   
        System.out.println("说活");
    }
    public void goHome(String tool){
   
        System.out.println("使用交通工具"+tool+"回家");
    }

    public double pay(double money){
   
        System.out.println("已经支付了"+String.format("%.2f",money)+"元");
        BigDecimal bg = new BigDecimal(money);
        /**
         *
         * 方法:setScale
         * 参数:
         * newScale - 要返回的 BigDecimal 值的标度。
         * roundingMode - 要应用的舍入模式。
         * 返回:
         * 一个 BigDecimal,其标度为指定值,其非标度值可以通过此 BigDecimal 的非标度值乘以或除以十的适当次幂来确定。
         */
        double result = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        System.out.println(result);
        return result;
    }

    /**
     * 如果number为零,出现异常,被除数不能为0
     * */
    public int divide(int number){
   
        return  10/number;
    }
}

切面类

package com.example.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

@Order(1) // 指定执行顺序
@Aspect // 定义为一个切面
@Component
public class AdviceForPerson {
   
    /**
     * 对GeneralPerson的所有方法进行拦截
     * */
    @Pointcut("execution(* com.example.aop.GeneralPerson.*(..))")
    public void pointcut(){
   }

    @Before("pointcut()"
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值