AOP功能代码实例---Spring源码从入门到精通(十七)

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: AOP功能代码实例---Spring源码从入门到精通(十七)

上篇文章主要介绍了@Profile注解:

可以对不同的开发环境(test,dev),选择性加载不同的组件,如果用AnnocationConfigApplicationContext,需要用无参构造函数,先自己getEnviroment,设置指定加载的test环境,还是dev环境。


IOC目录总结---Spring源码从入门到精通(十六)

Spring源码从入门到精通---@Profile(十五)



这篇文章主要介绍面向切面AOP:

动态代理,面向切面aop是一种开发思想,指在系统运行的情况下,吧代码插入到项目中指定的位子。


一、定义业务逻辑 类 和 切面类


首先必须把这两个类交给ioc容器管理,业务逻辑运行之后,切面类监听到业务逻辑正在运行,切面类可以用@pointCut指定监听的目标类,用切入点表达式,用@Aspect注解表示当前类是一个切面类。


导入aop切面maven包:

<!--Aop-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.3.12.RELEASE</version>
    </dependency>

业务逻辑类:

/**
 * @author keying
 */
public class MathCalculator {
    public int div(Integer i, Integer z) {
        //我们可以吧日志写在这里,但这是一种耦合的方式,并不符合aop编程思想
        //System.out.println("打印日志!");
        System.out.println("div正在计算。。。");
        return i / z;
    }
}

日志监听类:


从下面代码可以看到,用了

1、@Apect告诉spring这是一个切面类。

2、分别写了四个方法,开始start(注解 @Before),结束end(注解@After),returnSuccess返回成功(注解@AfterReturning),returnException业务异常(注解@AfterThrowing)。可以在每个方法上单独标注切入的目标。下面代码用@PointCut注解指定了一个公用的方法。

3、JoinPoint可以获取到切面目标的方法名 和 参数名等信息。

/**
 * @author keying
 * @Aspect:告诉springIOC,这是一个切面类
 */
@Aspect
public class LogAspects {
    /**
     * 抽取公共切入点表达式
     */
    @Pointcut("execution(public int com.alibaba.aop.MathCalculator.*(..))")
    public void pointCut() {
    }
    //业务方法之前切入
    //@Before("public int com.alibaba.aop.MathCalculator.div(Integer,Integer)")
    //@Before("public int com.alibaba.aop.MathCalculator.*(..)")
    @Before("pointCut()")
    public void start(JoinPoint joinPoint) {
        //获取切面目标方法名 和 参数列表
        Object[] objects = joinPoint.getArgs();
        System.out.println(joinPoint.getSignature().getName() + "计算开始 ---{" + Arrays.asList(objects) + "}");
    }
    //@After("public int com.alibaba.aop.MathCalculator.*(..)")
    @After("com.alibaba.aop.LogAspects.pointCut()")
    public void end() {
        System.out.println("计算结束 ---{}");
    }
    /**
     * 定义aop返回成功,用object接收返回成功参数
     * 重点,重点,重点:joinPoint必须写在参数第一位,否则spring无法解析
     */
    @AfterReturning(value = "pointCut()", returning = "object")
    public void returnSuccess(JoinPoint joinPoint, Object object) {
        System.out.println(joinPoint.getSignature().getName() + "计算返回成功 ---{" + object + "}");
    }
    @AfterThrowing(value = "pointCut()", throwing = "exception")
    public void returnException(Exception exception) {
        System.out.println("计算异常 ---{" + exception + "}");
    }
}

aop配置类:

下面用@Bean和@Import方法吧业务逻辑类 和 切面类交给springioc容器管理。@EnableAspectAutoProxy开启aop模式代理。

/**
 * AOP:动态代理。(编程思想)
 * 在程序运行时候,动态的将某段代码插入项目中指定位子的编程方式。
 *
 * 测试思想:
 * 定义一个业务逻辑类,在程序运行的时候,将他的日志打印(运行之前,运行之后,运行正常返回,计算异常等等)。
 * 定义一个日志切面类,动态的感知业务逻辑运行到哪里。
 * 通知方法:
 * 1)、前置通知(@Before):start,目标业务运行之前运行
 * 2)、后置通知(@After):end,目标业务运行结束之后运行。(无论正常结束还是异常结束)
 * 3)、返回通知(@AfterReturning):returnSuccess,目标业务运行成功
 * 4)、异常通知(@AfterThrowing):returnException,目标业务运行异常
 * 5)、环绕通知(@Around):动态代理,手动推进目标业务运行,joinPoint。
 *
 * @EnableAspectAutoProxy开启基于注解的aop模式代理
 *
 * @author keying
 */
@EnableAspectJAutoProxy
@Configuration
@Import({LogAspects.class})
public class MyConfigAop {
    @Bean(value = "mathCalculator")
    public MathCalculator mathCalculator(){
        return new MathCalculator();
    }
  /*  @Bean(value = "logAspects")
    public LogAspects logAspects(){
        return new LogAspects();
    }*/
}

junitTest:加载类改为aop配置类,从ioc容器中获取对象测试,不要自己创建对象测试,否则aop切面不生效。

/**
 * @author keying
 *
 * 自己实现AOP主要分为三步:
 * 1、自定义业务逻辑类 和 aop切面类,aop类加上@Aspect切面注解。
 * 2、给aop切面类每个方法加上注解,告知何时运行,切入点表达式@PointCut
 * 3、在配置类注解开启aop模式:@EnableAsceptAutoProxy
 */
public class AOPTestPointCut {
    @Test
    public void test() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(
            MyConfigAop.class);
        //这种自己创建的对象不会触发aop切面,需要从ioc容器中获取
      /*  MathCalculator mathCalculator = new MathCalculator();
        System.out.println(mathCalculator.div(1, 2));*/
        MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
        System.out.println("IOC容器获取后计算:" + mathCalculator.div(1, 2));
        applicationContext.close();
    }
}

运行之后可以看到,切面日志 在div运行之前有运行,在计算结束之后会返回成功,并且目标类的方法名称 、 参数 、返回值 都可以获取到。

image.png

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
3天前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
16 2
|
19天前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
8天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
9天前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
35 9
|
28天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
35 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
1月前
|
XML Java 数据格式
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
本文介绍了如何使用Spring框架的注解方式实现AOP(面向切面编程)。当目标对象没有实现接口时,Spring会自动采用CGLIB库进行动态代理。文中详细解释了常用的AOP注解,如`@Aspect`、`@Pointcut`、`@Before`等,并提供了完整的示例代码,包括业务逻辑类`User`、配置类`SpringConfiguration`、切面类`LoggingAspect`以及测试类`TestAnnotationConfig`。通过这些示例,展示了如何在方法执行前后添加日志记录等切面逻辑。
86 2
使用完全注解的方式进行AOP功能实现(@Aspect+@Configuration+@EnableAspectJAutoProxy+@ComponentScan)
|
14天前
|
缓存 监控 Java
|
14天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
10天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
22 0
|
1月前
|
Java BI API
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具
这篇文章介绍了如何在Spring Boot项目中整合iTextPDF库来导出PDF文件,包括写入大文本和HTML代码,并分析了几种常用的Java PDF导出工具。
407 0
spring boot 整合 itextpdf 导出 PDF,写入大文本,写入HTML代码,分析当下导出PDF的几个工具