Spring Boot AOP后置通知示例

后置通知用于在方法执行之后实现切面编程。它是一种通知类型,确保通知在方法执行后运行。我们使用@After注解来实现后置通知。

让我们通过一个例子来理解后置通知。

Spring Boot后置通知示例

步骤1:打开Spring Initializr http://start.spring.io。

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

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

步骤4:添加Spring Web依赖。

步骤5:单击Generate按钮。当我们单击Generate按钮时,它会将所有规格包装在一个jar文件中,并将其下载到本地系统。

fc66e64a0d8381c68278fec0b38df0b.png

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

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

File -> Import -> Existing Maven Projects -> Next -> Browse the Folder aop-after-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-after-advice-example</artifactId>  
<version>0.0.1-SNAPSHOT</version>    
<packaging>jar</packaging>    
<name>aop-after-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:打开AopAfterAdviceExampleApplication.java文件,并添加@EnableAspectJAutoProxy注解。

@EnableAspectJAutoProxy(proxyTargetClass=true)

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

AopAfterAdviceExampleApplication.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 AopAfterAdviceExampleApplication   
{  
public static void main(String[] args) {  
SpringApplication.run(AopAfterAdviceExampleApplication.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.After;  
import org.springframework.stereotype.Component;  
@Aspect  
@Component  
public class EmployeeServiceAspect   
{  
@After(value = "execution(* cn.javatiku.service.EmployeeService.*(..)) and args(empId, fname, sname)")  
public void afterAdvice(JoinPoint joinPoint, String empId, String fname, String sname) {  
System.out.println("After method:" + joinPoint.getSignature());  
System.out.println("Creating Employee with first name - " + fname + ", second name - " + sname + " and id - " + empId);  
}  
}  

在上面的类中:

  • execution(expression):表达式是要应用通知的方法。
  • @After:使用@After注解的方法在与切入点表达式匹配的所有方法之后执行。

完成所有模块后,项目目录如下所示:

81e5310245d2cf279ad8fbe31678f49.png

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

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

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

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

cfa81d8a42ad8b77daa9b6cbe20bc8d.png

在上面的输出中,我们分配了emId 102,firstName为Sachin和secondName为Bansal。

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

bb4ef29fab1e7403fa734d1faf1406b.png

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

21e71bc3046af58842a962e5f4e088b.png
在本节中,我们学习了后置通知的工作原理。在下一节中,我们将学习环绕通知的工作原理。

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