Spring Boot – 抛出After Advice的 AOP
Spring被广泛用于创建可扩展的应用程序。对于 Web 应用程序,Spring 提供。Spring MVC 是 Spring 的一个广泛使用的模块,用于创建可扩展的 Web 应用程序。而面向方面编程 (AOP),顾名思义,在编程中使用方面。它可以定义为将代码分解为不同的模块,也称为模块化,其中方面是模块化的关键单元。方面支持实现横切关注点,例如事务、日志记录等对业务逻辑来说并不重要的内容,而不会使代码核心与其功能混杂在一起。
注意:必须了解 Spring boot和面向方面编程
抛出After Advice是什么?
我们知道,spring 使用标准 J2SE 动态代理或 CGLIB 代理来代理目标对象。面向方面编程关注的是解决横切关注点,如日志记录和保护多个层,如控制器、服务层、DAO 等。
如果代理对象在执行目标方法时抛出异常,则执行抛出After Advice。请注意,只有当连接点与切入点表达式匹配时,对象才会被代理。请注意,Spring AOP 中的代理是在运行时创建的,连接点始终代表Spring AOP 中的方法 执行。
我们通过示例来看一下抛出建议之后的情况。
借助 Spring initializr 生成基础项目
前往 Spring Initializr 并复制下面提到的配置。
选择此配置后,单击生成项目,解压 ZIP 文件并在您选择的任何 IDE 中打开它。
还有一个依赖项需要添加,spring 从添加依赖项列表中删除了 AOP 启动器,因此我们必须手动添加它,只需将下面提到的依赖项添加到您的 pom.xml 文件中即可。
- XML
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> |
步骤 1:首先,让我们在com.geeksforgeeks.demo下创建一个名为dao 的包,我们将在其中创建模拟数据访问对象。通常,项目在控制器和dao之间包含一个中间层,称为服务层,但为了简单起见,我们将直接将数据从dao传输到控制器。
例子:
- Java
// Java Program to illustrate MockDAO Class
// Importing required classes import java.util.Arrays; import java.util.List; import org.springframework.stereotype.Repository;
// Annotation @Repository
// Class public class MockDAO {
// Not actually accessing a database, // just giving a mock data public List<String> getEmployees(boolean exception) { if (exception) { throw new RuntimeException("You asked for it"); }
return Arrays.asList("Mary", "Jerome", "Vyom"); } } |
@Repository用于指定该类提供存储、更新、删除等机制。但为了简单起见,我们只添加读取操作。我们有一个名为 exception 的参数,它将用作标志,是否抛出异常。
第 2 步:现在我们已经设置好了dao,接下来让我们设置控制器,在com.geeksforgeeks.demo下创建一个名为controller 的包
例子:
- Java
// Java Program to Illustrate DefaultWebController Class
// Importing required classes import com.geeksforgeeks.springbootaopafterthrowing.dao.MockDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping;
// Annotation @Controller
// Class public class DefaultWebController {
// Class data member private final MockDAO mockDAO;
// Annotation @Autowired public DefaultWebController(MockDAO mockDAO) { // This keyword refers to current instance itself this.mockDAO = mockDAO; }
// Annotation @GetMapping("/")
// Method public String homePage(Model model) { model.addAttribute("list", mockDAO.getEmployees(false)); return "index"; } } |
控制器下没有什么特别的,我们只是为默认登陆页面指定一个获取映射,向模型添加一个属性,并传递给index.html页面。
步骤3:之后,我们将在resources.templates包下添加index.html页面。
- HTML
<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Homepage</title> </head> <body> <table> <thead> <tr> <th>Name:</th> </tr> </thead> <tbody> <tr th:each="emp : ${list}"> <td th:text="${emp}"></td> </tr> </tbody> </table> </body> </html> |
不是一个花哨的 HTML 页面,只是一个非常简单的页面。如果您不了解 Thymeleaf,也不用担心,我们基本上访问了由DefaultWebController传递的模型属性,因为传递了一个列表,我们只需遍历每个条目并将其打印出来。
我们有在系统上运行它的基本设置,并检查 Web 应用程序现在是否正常运行(没有方面部分)。
步骤 4:只需在终端中打开项目并运行
mvn spring-boot:run
该项目将启动,打开您的浏览器,然后打开http://localhost:8080/,您应该会看到类似的页面 -
输出
步骤 5:到达此步骤后,现在是时候向我们的代码添加一个方面了。因此,在“com.geeksforgeeks.demo”下创建一个名为“aspect ”的包
例子
- Java
// Java Program to Illustrate LoggingAspect Class
// Importing required classes import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component;
// Annotation @Aspect @Component
// Class public class LoggingAspect {
// Annotation @AfterThrowing( "execution(public java.util.List com.geeksforgeeks.demo" + ".dao.MockDAO.getEmployees(..))")
public void afterThrowingExceptionAdvice() { // Print statement System.out.println( "\n ======>> Oh No an exception was thrown\n"); } } |
Spring AOP 在运行时生成代理,因此我们需要使用@Component注释类,这些类将用作 bean 并由 spring 在后台注入。@Aspect指定这是一个方面,它来自 AspectJ 库。
@AfterThrowing注释的作用正如其名称所示,它在切入点表达式中指定的方法抛出异常后执行。抛出异常后,程序只会打印到控制台。
切入点表达式指定应执行建议的方法 -
public java.util.List com.geeksforgeeks.demo.dao.MockDAO.getEmployees(..)
这是带有返回类型完整路径和方法名称本身的方法名称,(..) 匹配具有 0 个或多个任意类型参数的方法。
步骤 6:现在让我们看看实际效果,只需在控制器代码中将false更改为true -
model.addAttribute("list", mockDAO.getEmployees(true));
再次使用mvn spring-boot:run运行该程序,程序启动后只需访问http://localhost:8080/
耶,成功了,页面加载失败,因为我们在返回视图名称之前抛出了异常,因此无法将其转发给视图解析器。您应该看到如下所示的输出:
输出
而我们的终端输出应该类似如下所示:
终端输出