I. 介绍
Spring AOP概述:
Spring AOP是基于代理模式实现的,它提供了一种方便的方式来处理日志记录、安全性、事务管理等通用任务。AOP通过在核心业务逻辑代码外部织入切面(aspect),从而实现这些通用任务。在Spring中,切面是由普通的Java类定义的,而通知(advice)是要在切面中执行的方法。通过使用Spring AOP,我们可以将关注点分离出来,并将其应用到多个对象和方法中。这种分离可以提高代码的可重用性,同时也可以减少代码的重复性。
Spring AOP适用于那些需要在多个对象和方法中实现通用任务的场景,例如日志记录、事务管理、异常处理等。它可以通过将这些通用任务封装到一个切面中来实现代码的复用。同时,Spring AOP还提供了多种类型的通知,例如前置通知、后置通知、环绕通知、异常通知和最终通知,这些通知可以在不同的场景下使用。
总之,Spring AOP为我们提供了一种非常方便的方式来处理通用任务,并将其应用到多个对象和方法中。它的优点包括提高代码的可重用性和减少代码的重复性,适用于需要实现通用任务的场景,例如日志记录、事务管理、异常处理等。
AOP应用场景:
日志记录:AOP可以在不修改原有代码的情况下,通过织入切面实现日志记录功能,方便对系统运行情况进行监控和排查问题。
安全控制:通过AOP可以对系统进行安全控制,比如对某些方法进行权限验证、防止SQL注入等。
性能监控:通过AOP可以对系统的性能进行监控,比如统计某些方法的响应时间、调用次数等。
事务管理:通过AOP可以对事务进行统一管理,比如在事务开始时进行事务开启,在事务结束时进行提交或回滚。
异常处理:AOP可以帮助开发人员处理异常,比如记录异常日志、发送告警信息等。
II. 实现日志记录
定义Logger类:
/**
* 这是一个日志记录器类,用于打印出日志信息。
* Author: RedStar
* Email: CYH.RedStar@outlook.com
* Date: 2023/3/28
*/
public class Logger {
/**
* 检查方法,用于检查日志记录器是否正常工作。
*/
public void check() {
System.out.println("check");
}
/**
* 日志打印方法,用于打印日志信息。
*/
public void logPrint() {
System.out.println("logPrint");
}
/**
* 异常方法,用于打印出异常信息。
*/
public void exception() {
System.out.println("exception");
}
/**
* 销毁方法,用于销毁日志记录器。
*/
public void distroy() {
System.out.println("distroy");
}
}
III. 示例代码演示
编写BookService接口
/**
* 这个接口定义了对图书信息进行增、删、改、查操作的方法。
* Author: RedStar
* Email: CYH.RedStar@outlook.com
* Date: 2023/3/28
*/
public interface BookService {
/**
* 添加方法,用于向图书列表中添加一本新书。
*/
void add();
/**
* 插入方法,用于向指定位置插入一本新书。
*/
void insert();
/**
* 更新方法,用于更新一本图书的信息。
*/
void update();
/**
* 删除方法,用于删除一本图书的信息。
*/
void delete();
}
编写BookServiceImpl实现类
/**
* 这个类是 BookService 接口的实现类,用于对图书信息进行增、删、改、查操作。
* Author: RedStar
* Email: CYH.RedStar@outlook.com
* Date: 2023/3/28
*/
public class BookServiceImpl implements BookService {
/**
* 添加方法,用于向图书列表中添加一本新书。
*/
@Override
public void add() {
System.out.println("add");
}
/**
* 插入方法,用于向指定位置插入一本新书。
*/
@Override
public void insert() {
System.out.println("insert");
}
/**
* 更新方法,用于更新一本图书的信息。
*/
@Override
public void update() {
System.out.println("update");
}
/**
* 删除方法,用于删除一本图书的信息。
*/
@Override
public void delete() {
System.out.println("delete");
}
}
配置Spring容器和AOP增强 spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<!--这是 Spring 配置文件-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--1. 把所有类的对象交给 IOC 容器进行管理-->
<bean id="logger" class="com.cyh.logger.Logger"/>
<bean id="bookService" class="com.cyh.service.impl.BookServiceImpl"/>
<!--2. AOP 的配置:让增强类的哪个方法动态进行何种增强核心类的哪个方法-->
<aop:config>
<aop:aspect id="check" ref="logger">
<!--在 BookServiceImpl 类的所有方法执行之前调用 check 方法-->
<aop:before method="check" pointcut="execution(* *..BookServiceImpl.*(..))"/>
<!--在 BookServiceImpl 类的所有方法执行之后调用 logPrint 方法-->
<aop:after-returning method="logPrint" pointcut="execution(* *..BookServiceImpl.*(..))"/>
<!--在 BookServiceImpl 类的任意方法抛出异常时调用 exception 方法-->
<aop:after-throwing method="exception" pointcut="execution(* *..BookServiceImpl.*(..))"/>
<!--在 BookServiceImpl 类的所有方法执行之后调用 distroy 方法-->
<aop:after method="distroy" pointcut="execution(* *..BookServiceImpl.*(..))"/>
</aop:aspect>
</aop:config>
</beans>
编写测试类Test01
/**
* 这个类用于测试 BookService 接口的实现类的功能。
* Author: RedStar
* Email: CYH.RedStar@outlook.com
* Date: 2023/3/28
*/
public class Test01 {
BookService bookService;
/**
* 测试方法,用于测试 BookService 接口的实现类的功能。
*/
@Test
public void test() {
// 从配置文件中读取 Spring 容器
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
// 从容器中获取 BookService 的实现类
BookService bean = context.getBean(BookService.class);
// 调用方法测试其功能
bean.add();
System.out.println("---------------");
bean.delete();
System.out.println("---------------");
bean.update();
System.out.println("---------------");
bean.insert();
}
}
测试结果:
IV. 总结
AOP的优点及适用场景:
AOP的优点是:能够将与业务无关的横切关注点进行解耦,提高代码的复用性和可维护性;同时,AOP也能够对代码进行集中管理,方便统一修改和调整,降低代码维护成本。
AOP适用于横切关注点比较多的场景,比如日志记录、权限控制、性能监控等,可以通过AOP技术将这些横切关注点与业务逻辑进行解耦,使得业务逻辑更加清晰简洁,易于理解和维护。同时,AOP也适用于多个模块共同使用同一个功能的场景,可以通过AOP技术实现该功能的集中管理和统一调整。
使用AOP实现日志记录和异常处理的好处:
解耦和复用:将日志记录和异常处理这样的非业务逻辑从业务代码中抽离出来,通过AOP统一处理,可以有效降低代码的耦合度,同时也提高了这些功能代码的复用性。
代码简洁清晰:将这些非业务逻辑从业务代码中移除后,业务代码的复杂度得到了降低,代码变得更加简洁清晰,易于维护和扩展。
代码可控性:通过AOP可以对应用程序的运行状态进行监控和控制,从而提高了应用程序的可控性。
代码安全性:通过AOP实现异常处理可以保证应用程序在出现异常时的稳定性,从而提高了应用程序的安全性。