Spring Aop和事务
-
SpringAop是什么
-
特点
-
实现原理
-
通知
-
aop坐标
Spring + Aop
spring:是一个轻量级的开源框架,有三层架构。分别是:
-
Web层:Spring MVC(model+view+controller);
-
业务层 :Spring的IoC(控制反转,将设计好的对象交给控制器处理,而不是内部处理);
-
持久层 :Spring的JDBC等持久层框架。
Aop:是spring的核心之一,中文全称:面向切面编程。在网上看的博客、文章术语都很官方,我是这么理解的:对于解决一样的验证性问题,提出一个公共方法,每个接口都来调用这个接口,就不用每个接口ctrl+c,ctrl+v这么麻烦了。它允许程序员在不修改源代码的情况下,为程序添加新功能或修改现有功能。
Aop是一种思想,而SpringAop是一种实现框架。
SpringAop特点
- 解耦:AOP允许程序员将代码切分为不同的方面,使得各个部分可以独立开发、测试和部署。这有助于降低代码之间的耦合度,提高程序的可维护性和可扩展性。
- 模块化:AOP支持将功能划分为模块,从而使得程序员可以更容易地理解和维护代码。这也有助于提高代码的重用性和灵活性。
- 横切关注点:AOP允许程序员将某些功能(如日志、事务管理、安全性等)从核心业务逻辑中分离出来,从而使得这些功能可以在多个地方复用。这有助于减少代码重复和提高开发效率。
- 声明式编程:AOP支持声明式编程,程序员可以定义切面,指定它们应该在何时何地应用。
- 灵活性:AOP允许程序员在不修改源代码的情况下,为程序添加新功能或修改现有功能。
总之,AOP是一种编程范式,它通过将代码切分为不同的方面,实现了解耦、模块化和重用,从而提高了程序的可维护性、可扩展性和灵活性。
实现原理
-
切面(Aspect):切面是AOP的核心概念,它表示一个关注点的模块化。切面可以包含与特定功能相关的代码,例如日志、事务管理、安全性等。通过将代码划分为不同的切面,AOP允许程序员在不修改源代码的情况下为程序添加新功能或修改现有功能。
-
连接点(Join Point):连接点是在程序执行过程中可以插入切面的点。例如,方法调用、异常处理、属性访问等都可以作为连接点。
-
通知(Advice):通知是在切面上定义的,用于指导AOP如何处理特定连接点的方法。通知可以分为前置通知(Before)、后置通知(After)、异常通知(Throwing)和返回通知(Returning)四种。通过在切面中定义通知,程序员可以控制切面在何时何地应用。(下面会讲到)
-
代理(Proxy):AOP通过动态代理技术实现切面的应用。当程序执行到指定连接点时,AOP会创建一个代理对象,将切面的通知应用到代理对象上,然后调用原始方法。这样,切面就可以在不修改源代码的情况下,对程序的行为进行干预。
-
容器(Container):容器是AOP框架的核心组件,它负责管理切面的加载、实例化和应用。容器可以自动扫描程序中的切面,并根据需要将切面应用到指定连接点上。
通过这些原理,AOP实现了将代码切分为不同的方面,然后在运行时将它们动态地组合在一起,从而实现了解耦、模块化和重用,提高了程序的可维护性、可扩展性和灵活性。
通知
这个很重要!!!
xml方式配置在resources文件夹下的application.xml文件中。
主要有以下几个类型:
前置通知标签:<aop:before> 注解:@Before
示例:
xml
aop:before </aop:before>
<before>
标签定义了一个前置通知,它的代码将在目标方法执行之前执行注解:
@Before(“execution(* com.example.service..(…))”) public void beforeAdvice(JoinPoint joinPoint) { // 在这里编写前置通知的代码 }
@Before
注解定义了一个前置通知,它将在com.example.service
包下的所有方法的执行之前执行。后置通知标签: <aop:AfterReturning> 注解:@AfterReturning
示例:
xml:
aop:AfterReturning </aop:AfterReturning>
<after>
标签定义了一个后置通知,它的代码将在目标方法执行之后执行注解:
@After("execution(* com.example.service.*.*(..))") public void afterAdvice(JoinPoint joinPoint) { // 在这里编写后置通知的代码 }
@After
注解定义了一个后置通知,它将在com.example.service
包下的所有方法的执行之后执行环绕通知标签: <aop:Around> 注解: @Around
示例:
<aop:config> <aop:aspect ref="logManager"> <aop:around method="printLog" pointcut="execution(* com.gcxy.service..*.*(..))"></aop:around> </aop:aspect> </aop:config>
异常抛出通知标签: <aop:AfterThrowing> 注解: @AfterThrowing
示例:
@Throws(MyException.class) public void myMethod() { // 在这里编写目标方法的代码,可能会抛出MyException异常 }
在这个示例中,
@Throws
注解定义了一个异常抛出通知,它将在目标方法抛出MyException
异常时执行。最终通知标签: <aop:After> 注解: @After
实例:
假设我们有一个
UserService
类,其中有一个saveUser
方法。我们希望在saveUser
方法执行完成后执行一段代码。首先,我们需要在
UserService
类上添加@Service
注解,以将其定义为一个Spring服务:@Service public class UserService { // 在这里编写UserService类的代码 }
接下来,我们将在
saveUser
方法上添加@After
注解,以定义一个<aop:After>
通知:@Service public class UserService { @After("execution(* com.example.service.UserService.*(..))") public void afterSaveUser() { // 在这里编写<aop:After>通知的代码 System.out.println("User saved successfully."); } public void saveUser(User user) { // 在这里编写saveUser方法的代码 } }
在这个示例中,
@After
注解定义了一个<aop:After>
通知,它将在UserService
类下的所有方法的执行完成后执行。s需要导入的aop坐标有:<groupId>org.example</groupId> <artifactId>aoptest</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.6</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
我也是个小小菜鸟,自己在网上看博客,还有巩固了老师上课讲的内容和笔记,就整理了这些,大家还有不懂的建议去看看其他博客。呼呼,吗喽的命也是命。
-