药剂学教学网站的建设福田公司门口
web/
2025/9/30 14:18:04/
文章来源:
药剂学教学网站的建设,福田公司门口,定制网站成本多少,学网站建设学校国庆中秋特辑系列文章#xff1a;
国庆中秋特辑#xff08;八#xff09;Spring Boot项目如何使用JPA
国庆中秋特辑#xff08;七#xff09;Java软件工程师常见20道编程面试题
国庆中秋特辑#xff08;六#xff09;大学生常见30道宝藏编程面试题
国庆中秋特辑
国庆中秋特辑八Spring Boot项目如何使用JPA
国庆中秋特辑七Java软件工程师常见20道编程面试题
国庆中秋特辑六大学生常见30道宝藏编程面试题
国庆中秋特辑五MySQL如何性能调优下篇
国庆中秋特辑四MySQL如何性能调优上篇
国庆中秋特辑三使用生成对抗网络GAN生成具有节日氛围的画作深度学习框架 TensorFlow 和 Keras 来实现
国庆中秋特辑二浪漫祝福方式 使用生成对抗网络GAN生成具有节日氛围的画作
国庆中秋特辑一浪漫祝福方式 用循环神经网络RNN或长短时记忆网络LSTM生成祝福诗词 目录 一、Spring AOP 简介二、Spring AOP 原理三、Spring AOP 案例分析四、Spring AOP 提供了两种动态代理方式 Spring AOPAspect-Oriented Programming面向切面编程是 Spring 框架的一个重要模块。
一、Spring AOP 简介
Spring AOPAspect-Oriented Programming面向切面编程是 Spring 框架的一个重要模块用于提供声明式的事务管理、日志记录、性能监控等功能。Spring AOP 底层依赖于 AspectJ 实现可以与 Spring 框架无缝集成提供一种更加简单、直观的方式来处理企业应用中的常见问题。
二、Spring AOP 原理
代理机制 Spring AOP 采用代理机制实现可以分为 JDK 动态代理和 CGLIB 动态代理。JDK 动态代理是通过实现目标类的接口生成目标类的代理对象CGLIB 动态代理是通过继承目标类生成目标类的子类作为代理对象。通知Advice 通知是 Spring AOP 中实现切面功能的核心可以分为五种类型Before、After、AfterReturning、AfterThrowing 和 Around。通知的作用是在目标方法执行前、后或者抛出异常时执行特定的逻辑实现对目标方法的增强。切入点Pointcut 切入点是 Spring AOP 中定义的一个表达式用于指定哪些方法需要被增强。切点表达式可以使用 AspectJ 语言来编写非常灵活。通过定义切入点可以精确地控制哪些方法需要被增强。切面Aspect 切面是 Spring AOP 中的一种组件包含切点和通知。切面可以将通用的逻辑如日志、事务管理等封装在一起便于管理和维护。在 Spring AOP 中可以通过 XML 配置文件或者 Java 代码来定义切面。自动代理 Spring AOP 框架支持自动代理可以在运行时自动为指定类生成代理对象。自动代理的核心是 Spring AOP 容器负责管理代理对象、切面和通知。通过自动代理可以简化开发者的操作提高开发效率。
三、Spring AOP 案例分析
以下通过一个简单的案例来演示 Spring AOP 的使用。
配置文件 首先创建一个配置文件 applicationContext.xml用于定义目标类和切面类。
beans xmlnshttp://www.springframework.org/schema/beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aop xsi:schemaLocationhttp://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 idtarget classcom.example.TargetClass/bean!-- 定义切面类 -- bean idaspect classcom.example.AspectClass/bean!-- 开启自动代理 -- aop:config proxy-target-classtrue !-- 指定切入点表达式 -- aop:aspect refaspect aop:before pointcutexecution(* com.example.TargetClass.*(..)) methodcom.example.AspectClass.beforeAdvice/aop:before aop:after pointcutexecution(* com.example.TargetClass.*(..)) methodcom.example.AspectClass.afterAdvice/aop:after /aop:aspect /aop:config
/beans 目标类TargetClass 目标类是一个简单的计算类包含两个方法doAdd 和 doSubtract。
package com.example;
public class TargetClass { public int doAdd(int a, int b) { System.out.println(TargetClass doAdd method called); return a b; }public int doSubtract(int a, int b) { System.out.println(TargetClass doSubtract method called); return a - b; }
}切面类AspectClass 切面类包含两个通知方法beforeAdvice 和 afterAdvice分别用于在目标方法执行前和执行后执行特定逻辑。
package com.example;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
public class AspectClass { Before(execution(* com.example.TargetClass.*(..))) public void beforeAdvice(JoinPoint joinPoint) { System.out.println(Before advice: joinPoint.getSignature().getName()); }After(execution(* com.example.TargetClass.*(..))) public void afterAdvice(JoinPoint joinPoint) { System.out.println(After advice: joinPoint.getSignature().getName()); }
}测试类TestClass 测试类用于测试 Spring AOP 的效果。
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestClass { public static void main(String[] args) { ApplicationContext context new ClassPathXmlApplicationContext(applicationContext.xml); TargetClass target (TargetClass) context.getBean(target);int result1 target.doAdd(2, 3); int result2 target.doSubtract(5, 2);System.out.println(Result 1: result1); System.out.println(Result 2: result2); }
}运行测试类输出结果如下
TargetClass doAdd method called
Before advice: doAdd
After advice: doAdd
Result 1: 5
TargetClass doSubtract method called
Before advice: doSubtract
After advice: doSubtract
Result 2: 3 从输出结果可以看出在目标方法执行前和执行后分别执行了 beforeAdvice 和 afterAdvice 方法说明 Spring AOP 已经成功实现了对目标方法的增强。
四、Spring AOP 提供了两种动态代理方式
JDK 动态代理和 CGLIB 动态代理。JDK 动态代理是基于接口实现的而 CGLIB 动态代理是基于类实现的。这两种代理方式在性能上有一定的差别JDK 动态代理更适合用于接口较多的场景而 CGLIB 动态代理则更适合用于类较多的场景。 4.1 下面是一个简单的 Spring AOP JDK 动态代理示例演示了如何使用 Spring AOP 实现日志切面
首先创建一个切面类Aspect包含一个通知Advice
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
Aspect
Component
public class LoggingAspect {Pointcut(execution(* com.example.service.*.*(..))) public void serviceMethods() { }Before(serviceMethods()) public void logBefore(JoinPoint joinPoint) { System.out.println(Before method: joinPoint.getSignature().getName()); }AfterReturning(pointcut serviceMethods(), returning result) public void logAfterReturning(JoinPoint joinPoint, Object result) { System.out.println(After returning method: joinPoint.getSignature().getName()); System.out.println(Result: result); }
}接下来创建一个目标类Target Class包含一个需要增强的方法
package com.example.service;
import org.springframework.stereotype.Service;
Service
public class TargetService {public String sayHello(String name) { System.out.println(Hello, name); return Hello, name; }
}然后创建一个 Spring 配置类启用 AOP 支持并扫描包含切面和目标类的包
package com.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
Configuration
EnableAspectJAutoProxy
ComponentScan(basePackages {com.example.aspect, com.example.service})
public class AppConfig {
}最后创建一个测试类使用 Spring AOP 提供的 API 调用目标类的方法
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
Component
public class Test {public static void main(String[] args) { ApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class); TargetService targetService context.getBean(TargetService.class); String result targetService.sayHello(World); System.out.println(Result: result); }
}运行测试类你将看到目标方法被切面增强的日志输出。这个示例展示了如何使用 Spring AOP JDK 动态代理实现简单的日志切面以记录目标方法执行的前后状态。这有助于实现代码的重用和提高可维护性。
4.2 下面是一个简单的 Spring AOP CGLIB 动态代理示例演示了如何使用 Spring AOP 实现日志切面
首先创建一个切面类Aspect包含一个通知Advice
package com.example.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
Aspect
Component
public class LoggingAspect {Pointcut(execution(* com.example.service.*.*(..))) public void serviceMethods() { }Before(serviceMethods()) public void logBefore(JoinPoint joinPoint) { System.out.println(Before method: joinPoint.getSignature().getName()); }AfterReturning(pointcut serviceMethods(), returning result) public void logAfterReturning(JoinPoint joinPoint, Object result) { System.out.println(After returning method: joinPoint.getSignature().getName()); System.out.println(Result: result); }
}接下来创建一个目标类Target Class包含一个需要增强的方法
package com.example.service;
import org.springframework.stereotype.Service;
Service
public class TargetService {public String sayHello(String name) { System.out.println(Hello, name); return Hello, name; }
}然后创建一个 Spring 配置类启用 AOP 支持并扫描包含切面和目标类的包
package com.example;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
Configuration
EnableAspectJAutoProxy
ComponentScan(basePackages {com.example.aspect, com.example.service})
public class AppConfig {
}最后创建一个测试类使用 Spring AOP 提供的 API 调用目标类的方法
package com.example;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;
Component
public class Test {public static void main(String[] args) { ApplicationContext context new AnnotationConfigApplicationContext(AppConfig.class); TargetService targetService context.getBean(TargetService.class); String result targetService.sayHello(World); System.out.println(Result: result); }
}运行测试类你将看到目标方法被切面增强的日志输出。这有助于实现代码的重用和提高可维护性。 需要注意的是CGLIB 动态代理需要 TargetService 类实现 equals() 和 hashCode() 方法否则会报错。这是因为 CGLIB 需要生成目标类的代理类而如果 TargetService 类没有实现 equals() 和 hashCode() 方法那么生成的代理类将无法正确处理目标类的对象。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/84493.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!