📜  Spring Boot – 抛出建议后的 AOP

📅  最后修改于: 2022-05-13 01:55:27.505000             🧑  作者: Mango

Spring Boot – 抛出建议后的 AOP

Spring 广泛用于创建可扩展的应用程序。对于 Web 应用程序 Spring 提供。 Spring MVC 是一个广泛使用的 spring 模块,用于创建可扩展的 Web 应用程序。顾名思义,面向方面的编程(AOP)在编程中使用方面。它可以定义为将代码分解为不同的模块,也称为模块化,其中方面是模块化的关键单元。方面支持横切关注点的实现,例如事务、日志记录,这些不是业务逻辑的核心,而不会使代码核心与其功能杂乱无章。

投掷后的建议是什么?

我们知道 spring 使用标准的 J2SE 动态代理或 CGLIB 代理来代理目标对象。面向方面的编程涉及解决横切关注点,如日志记录和保护多个层,如控制器、服务层、DAO 等。

如果代理对象在执行目标方法时抛出异常,则会执行抛出后通知。请注意,仅当连接点切入点表达式匹配时才代理该对象。请注意,Spring AOP 中的代理是在运行时创建的,连接点始终代表 Spring AOP 中的方法执行

让我们在示例的帮助下提出建议后看看。

借助 Spring initializr 生成基础项目

前往 Spring Initializr 并复制下面提到的配置。

选择此配置后,单击生成项目,解压缩 ZIP 文件并在您选择的任何 IDE 中打开它。

还要添加一个依赖项,spring 从添加依赖项列表中删除了 AOP 启动器,因此我们必须手动添加它,只需将下面提到的依赖项添加到您的 pom.xml 文件中。

XML

    org.springframework.boot
    spring-boot-starter-aop


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 getEmployees(boolean exception)
    {
        if (exception) {
            throw new RuntimeException("You asked for it");
        }
 
        return Arrays.asList("Mary", "Jerome", "Vyom");
    }
}


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";
    }
}


HTML



    
    Homepage



    
    
        
    
    
    
    
        
    
    
Name:


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");
    }
}



第 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 getEmployees(boolean exception)
    {
        if (exception) {
            throw new RuntimeException("You asked for it");
        }
 
        return Arrays.asList("Mary", "Jerome", "Vyom");
    }
}


@Repository用于指定类提供存储、更新、删除等机制。但为了简单起见,我们将只添加读取操作。我们有一个称为异常的参数,它将用作标志,是否抛出异常。

第二步:既然我们已经设置好了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";
    }
}


控制器下没什么特别的,我们只是为默认登陆页面指定一个get映射,给模型添加一个属性,然后传递给index.html页面。

第三步:之后,我们将在resources.templates包下添加index.html页面。

HTML




    
    Homepage



    
    
        
    
    
    
    
        
    
    
Name:


不是一个花哨的 HTML 页面,只是一个非常简单的页面。如果您不了解 Thymeleaf,请不要担心,我们基本上访问由DefaultWebController传递的模型属性,因为传递了一个列表,我们只需遍历每个条目并将其打印出来。

我们有基本的设置来在我们的系统上运行它并检查网络应用程序现在是否正常工作(没有方面部分)。

第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/

是的,成功页面加载失败,因为我们在返回视图名称之前引发了异常,可以将其转发给视图解析器。您应该看到如下输出,如下所示:

输出

我们的终端输出应该类似于如下所示:

终端输出