Spring Boot AOP前置通知

前置通知在面向切面编程中用于实现横切关注点。它是一种通知类型,确保在方法执行之前运行通知。我们使用@Before注解来实现前置通知。

让我们通过一个示例来理解前置通知。

Spring Boot前置通知示例 步骤1:打开Spring Initializr http://start.spring.io。

步骤2:提供Group名称。我们提供了Group名称为cn.javatiku。

步骤3:提供Artifact Id。我们提供了Artifact Id为aop-before-advice-example。

步骤4:添加Spring Web依赖。

步骤5:点击Generate按钮。当我们点击Generate按钮时,它将所有规范包装在一个jar文件中并下载到本地系统。
261b6def1e400050a51380356fb44c0.png

步骤6:解压下载的jar文件。

步骤7:使用以下步骤导入文件夹:

File -> Import -> Existing Maven Projects -> Next -> Browse the Folder aop-before-advice-example -> Finish.

步骤8:打开pom.xml文件并添加以下AOP依赖项。这是一个使用Spring AOP和AspectJ的面向切面编程的启动器。

    <dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-aop</artifactId>  
    </dependency>  
    </dependencies>  

pom.xml

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">  
    <modelVersion>4.0.0</modelVersion>  
    <groupId>cn.javatiku</groupId>  
    <artifactId> aop-before-advice-example</artifactId>  
    <version>0.0.1-SNAPSHOT</version>    
    <packaging>jar</packaging>    
    <name>aop-before-advice-example</name>  
        <description>Demo project for Spring Boot</description>  
        <parent>  
            <groupId>org.springframework.boot</groupId>  
            <artifactId>spring-boot-starter-parent</artifactId>  
            <version>2.2.2.RELEASE</version>  
            <relativePath /> <!-- lookup parent from repository -->  
        </parent>  
        <properties>  
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>  
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>  
            <java.version>1.8</java.version>  
        </properties>  
        <dependencies>  
            <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-web</artifactId>  
            </dependency>  
        <dependency>  
                <groupId>org.springframework.boot</groupId>  
                <artifactId>spring-boot-starter-aop</artifactId>  
            </dependency>  
        </dependencies>  
      
        <build>  
            <plugins>  
                <plugin>  
                    <groupId>org.springframework.boot</groupId>  
                    <artifactId>spring-boot-maven-plugin</artifactId>  
                </plugin>  
            </plugins>  
        </build>  
    </project>  

步骤9:打开AopBeforeAdviceExampleApplication.java文件,并添加@EnableAspectJAutoProxy注解。

@EnableAspectJAutoProxy(proxyTargetClass=true)

@EnableAspectJAutoProxy用于启用对使用AspectJ的@Aspect注解标记的组件的支持。它与@Configuration注解一起使用。我们可以使用proxyTargetClass属性来控制代理的类型,默认值为false。

AopBeforeAdviceExampleApplication.java

package cn.javatiku;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AopBeforeAdviceExampleApplication
{
    public static void main(String[] args) {
        SpringApplication.run(AopBeforeAdviceExampleApplication.class, args);
    }
}

步骤10:创建一个名为cn.javatiku.model的包。

步骤11:在cn.javatiku.model包下创建一个模型类。我们创建了一个名为Employee的类。在该类中定义以下内容:

  • 定义三个类型为String的变量empId、firstName和secondName。
  • 生成Getters和Setters方法。
  • 创建一个默认构造函数。

Employee.java

package cn.javatiku.model;  
public class Employee   
{  
private String empId;  
private String firstName;  
private String secondName;  
//default constructor  
public Employee()   
{  
}  
public String getEmpId()   
{  
return empId;  
}  
public void setEmpId(String empId)   
{  
this.empId = empId;  
}  
public String getFirstName()   
{  
return firstName;  
}  
public void setFirstName(String firstName)   
{  
this.firstName = firstName;  
}  
public String getSecondName()   
{  
return secondName;  
}  
public void setSecondName(String secondName)   
{  
this.secondName = secondName;  
}  
}  

步骤12:创建一个名为cn.javatiku.controller的包。

步骤13:在cn.javatiku.controller包下创建一个控制器类。我们创建了一个名为EmployeeController的类。

在控制器类中,我们定义了两个映射,一个用于添加员工,另一个用于删除员工。

EmployeeController.java

package cn.javatiku.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import cn.javatiku.model.Employee;
import cn.javatiku.service.EmployeeService;
@RestController
public class EmployeeController
{
    @Autowired
    private EmployeeService employeeService;
    @RequestMapping(value = "/add/employee", method = RequestMethod.GET)
    public cn.javatiku.model.Employee addEmployee(@RequestParam("empId") String empId, @RequestParam("firstName") String firstName, @RequestParam("secondName") String secondName)
    {
        return employeeService.createEmployee(empId, firstName, secondName);
    }
    @RequestMapping(value = "/remove/employee", method = RequestMethod.GET)
    public String removeEmployee( @RequestParam("empId") String empId)
    {
        employeeService.deleteEmployee(empId);
        return "Employee removed";
    }
}

步骤14:创建一个名为cn.javatiku.service的包。

步骤15:在cn.javatiku.service包下创建一个服务类。我们创建了一个名为EmployeeService的类。

在服务类中,我们定义了两个方法createEmployee和deleteEmployee。

EmployeeService.java

package cn.javatiku.service;
import org.springframework.stereotype.Service;
import cn.javatiku.model.Employee;
@Service
public class EmployeeService
{
    public Employee createEmployee( String empId, String fname, String sname)
    {
        Employee emp = new Employee();
        emp.setEmpId(empId);
        emp.setFirstName(fname);
        emp.setSecondName(sname);
        return emp;
    }
    public void deleteEmployee(String empId)
    {
    }
}

步骤16:创建一个名为cn.javatiku.aspect的包。

步骤17:在cn.javatiku.aspect包下创建一个切面类。我们创建了一个名为EmployeeServiceAspect的类。

在切面类中,我们定义了前置通知的逻辑。

EmployeeServiceAspect.java

package cn.javatiku.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class EmployeeServiceAspect
{
    @Before(value = "execution(* cn.javatiku.service.EmployeeService.*(..)) and args(empId, fname, sname)")
    public void beforeAdvice(JoinPoint joinPoint, String empId, String fname, String sname) {
        System.out.println("Before method:" + joinPoint.getSignature());
        System.out.println("Creating Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId);
    }
}

在上述类中:

  • execution(expression):expression表示要应用通知的方法。
  • @Before:将函数标记为要在被PointCut覆盖的方法之前执行的通知。

在创建了所有模块后,项目目录如下:

dc564ea0f5ad9c7f02ac551364035aa.png

我们已经设置好了所有模块。现在我们将运行应用程序。

步骤18:打开eAopBeforeAdviceExampleApplication.java文件并将其运行为Java应用程序。

步骤19:打开浏览器并调用以下URL:http://localhost:8080/add/employee?empId={id}&firstName={fname}&secondName={sname}

在上述URL中,/add/employee是我们在控制器类中创建的映射。我们使用两个分隔符(?和&)来分隔两个值。

bad588aaaf290c8018b54d88cf16df3.png

在上述输出中,我们分配了emId 101,firstName=Tim和secondName=Cook。

让我们来看一下控制台。我们可以看到,在调用EmployeeService类的createEmployee()方法之前,beforeAdvice()方法会被调用,如下所示。

2f9f5ae424a3c1b738fa6274b6518c3.png

类似地,我们也可以通过调用URL http://localhost:8080/remove/employee?empId=101来删除一个员工。它会返回消息"Employee removed",如下图所示。

Spring Boot AOP前置通知 在本节中,我们学习了前置通知的工作原理。

标签: spring, Spring教程, Spring语言学习, Spring框架, Spring框架教程, Spring框架高级教程, spring boot, spring boot入门教程, spring boot学习教程, spring boot下载, spring boot框架入门, spring boot面试题, spring boot笔试题, spring boot技术, t学习指南