首页 > 其他分享 >Spring(3)-AOP快速入手

Spring(3)-AOP快速入手

时间:2024-04-27 20:13:22浏览次数:28  
标签:SmartAnimalable 入手 Spring float 通知 AOP 方法 public

经过前面Spring(1)-粗解动态代理 - marigo - 博客园 Spring(2)-粗解横切关注点 - marigo - 博客园两篇内容,我们可以引入AOP了。

AOP的简单理解

AOP 的全称(aspect oriented programming) ,面向切面编程
我们在此之前接触的更多是OOP,也就是面向对象编程。OOP和AOP有什么异同,网上有很多详细地讲解,本文不做赘述,直接对什么是AOP进行说明。
在前面Spring(2)-粗解横切关注点 - marigo - 博客园中,比如有一个 A类,其中有很多方法,在使用的时候不是OOP那种 A.方法1() 的方式,而且通过动态代理,使用proxy.方法1()的方式调用。又引出了横切关注点的概念,有四个位置:前置通知、返回通知、异常通知、最终通知,这四个位置也就是代表着四个可能需要切入的方法。我们还写了一个非常简单的切面类,其中有很多方法,这些方法会被切入到四个横切关注点的任意位置。
image.png
这就是AOP的比较直观地理解,接下来就是AOP的快速入门。

AOP的快速入门

切面类中,框架 aspectj 声明通知的方法:
1. 前置通知:@Before
2. 返回通知:@AfterReturning
3. 异常通知:@AfterThrowing
4. 后置通知(最终通知):@After
5. 环绕通知:@Around,可以将以上四个通知合并管理

实例

需求

Spring(2)-粗解横切关注点 - marigo - 博客园的需求,大体要求就是打印输出:

前置通知
方法内部打印:result = 21.1
返回通知
最终通知

AOP代码实现

  1. 创建 SmartAnimalable 接口
public interface SmartAnimalable {  
    float getSum(float i, float j);  
    float getSub(float i, float j);  
}
  1. 创建 SmartAnimalable 接口的实现类 SmartDog
    1. 使用Spring框架,我们后面就不再手动new对象了,加入注解@Component,也就是当Spring启动后,将SmartDog自动注入到容器中
@Component  
public class SmartDog implements SmartAnimalable{  
    @Override  
    public float getSum(float i, float j) {  
        float result = i + j;  
        System.out.println("getSum() 方法内部打印 result= " + result);  
        return result;  
    }  
    @Override  
    public float getSub(float i, float j) {  
        float result = i - j;  
        System.out.println("getSub() 方法内部打印 result= " + result);  
        return result;  
    }  
}
  1. 创建切面类 SmartAnimalAspect
    1. 如何让Spring知道这是个切面类呢,需要加两个注解@Aspect和@Component,前者表示这是一个切面类,后者是将这个切面类注入到容器中
    2. 以前置通知为例进行注释讲解,其他三个位置同理,不做展开
    3. 这里就将前面写过两遍的 MyProxyProvider 动态代理类进行了封装,写起来简单,而且功能更强大
@Aspect  
@Component  
public class SmartAnimalAspect {  
    /**  
     * 前置通知:希望在目标方法执行之前执行  
     * @Before() 参数表示我们要把方法切入到哪里,格式是:访问修饰符 返回值 包名.类名.方法名(参数类型)
     * JoinPoint joinPoint:表示连接点对象,有很多有用的方法  
     * joinPoint.getSignature():获取方法签名对象  
     * joinPoint.getArgs():获取方法参数  
     * 方法签名就是目标方法的方法名:com.example.aspectj.SmartDog.getSum  
     */    
    @Before(value = "execution(public float com.example.aspectj.SmartDog.getSum(float ,float))")  
    public void showBeginLog(JoinPoint joinPoint) {  
        System.out.println("前置通知");  
        Signature signature = joinPoint.getSignature();  
        // 1. 在调用目标方法之前打印“方法开始”日志  
        System.out.println("日志--方法名:" + signature.getName() + "--方法开始--参数:" + Arrays.asList(joinPoint.getArgs()));  
    }  
}
  1. 配置bean.xml
    1. 自动扫描包
    2. 开启基于注解的AOP功能
<context:component-scan base-package="com.example.aspectj"/>  
<aop:aspectj-autoproxy/>
  1. 测试
public class ATest {  
    public static void main(String[] args) {  
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans07.xml");  
        // 通过接口获取注入的对象-本质上就是代理对象  
        SmartAnimalable bean = ioc.getBean(SmartAnimalable.class);  
        bean.getSum(1, 2);  
    }  
}

至此,我们就完成了AOP的快速入门。

补充

  1. 切面类中的方法名不做要求,但是建议采用规范的方法名showBeginLog()、showSuccessEndLog()、showExceptionLog()、showFinallyEndLog()
  2. 切入表达式可以模糊配置:@Before(value="execution(* com.example.aspectj.SmartDog.*(..))")
  3. 所有包下的所有类的所有方法都执行方法:@Before(value="execution(* *.*(..))")
  4. 当 spring 容器开启了 aop:aspectj-autoproxy/ , 我们获取注入的对象, 需要以接口的类型来获取, 因为我们注入的对象.getClass() 已经是代理类型了
  5. 当 spring 容器开启了 aop:aspectj-autoproxy/ , 我们获取注入的对象, 也可以通过 id 来获取, 但是也要转成接口类型
public class ATest {  
    public static void main(String[] args) {  
        ClassPathXmlApplicationContext ioc = new ClassPathXmlApplicationContext("beans07.xml");  
        // 通过接口获取注入的对象-本质上就是代理对象  
//        SmartAnimalable bean = ioc.getBean(SmartAnimalable.class);  
        SmartAnimalable bean2 = (SmartAnimalable) ioc.getBean("smartDog");  
        bean2.getSum(1, 2);  
    }  
}

标签:SmartAnimalable,入手,Spring,float,通知,AOP,方法,public
From: https://www.cnblogs.com/marigo/p/18162434

相关文章

  • Spring(4)-AOP使用细节
    有了Spring(3)-AOP快速入手-marigo-博客园的学习,大体知道AOP的使用,接下来我们对AOP的细节进行展开。AOP-切入表达式作用:通过表达式定位一个或者多个连接点连接点可以理解成我们要切入到哪个类的哪个具体方法语法:execution([权限修饰符][返回值类型][简单类名/全类名][......
  • (一)spring beans
    1.beanDefinition首先是承载class的载体,里面包含了许多如是否单例,属性值等内容。以下只是建议代码,重在理解概念packageorg.springframework.spring.beans.factory.config;/***@ClassName:BeanDefinition//类名*@Description://描述*@Author:10300//作者......
  • SpringBoot集成minio前后端联调
    基本配置初始化项目新建一个SpringBoot项目,集成lombokmybatis-plusminiohutool-core(可有可无)。新建一个数据表attachement,用于存储文件上传后在minio中的位置。droptableifexistsattachment;createtableattachment(idintauto_increment......
  • spring-securty-oauth2使用例子
    oauth2概念https://www.cnblogs.com/LQBlog/p/16996125.html环境搭建1.引入依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-oauth2</artifactId></depen......
  • spring boot
    链接:https://pan.baidu.com/s/1quiC-bqO5s3KgoLT5MWX7Q?pwd=412p提取码:412p1.Springboot入门springboot-简化了开发-比如-我们之前导入依赖--到需要自己写配置类-返回Beanspringboot帮我们简化了这个工程SpringBoot提供了一种快速使用Spring的方式,基于约定优于配置的思想sp......
  • 有意思!一个关于 Spring 历史的在线小游戏
    发现SpringOne的官网上有个好玩的彩蛋,分享给大家!进到SpringOne的官网,可以看到右下角有个类似马里奥游戏中的金币图标。点击该金币之后,会打开一个新的页面,进入下面这样一个名为:TheHistoryOfSpring的在线小游戏你可以使用上下左右的方向键来控制Spring的Logo一步步经历......
  • 一个通用的SpringBoot项目响应实体类Response
    packagecom.luky.vo;importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;importlombok.ToString;importorg.springframework.http.HttpStatus;@Data@ToString@AllArgsConstructor@NoArgsConstructorpublicclassResponse&......
  • SpringBoot+MyBatisPlus报错 Invalid value type for attribute 'factoryBeanObjectTy
    依赖版本org.springframework.boot:spring-boot-starter-web:3.2.5com.baomidou:mybatis-plus-boot-starter:3.5.5错误Invalidvaluetypeforattribute'factoryBeanObjectType'问题原因:这个问题是由于依赖传递导致,在MyBatis起步依赖中的myBatis-spring版本过低,导致程......
  • spring-接口大全
    1.Bean相关1.InitializingBeanInitializingBean接口为bean提供了初始化方法的方式,它只包括afterPropertiesSet方法,凡是继承该接口的类,在初始化bean的时候都会执行该方法。demo@ComponentpublicclassMyInitBeanimplementsInitializingBean{publicvoidafterPro......
  • springboot链接redis IPV6
    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><exclusions><exclusion>......