Spring Boot AOP抛出后建议

抛出后建议是Spring AOP中的一种建议类型。它确保在方法抛出异常时运行建议。我们使用@AfterThrowing注解来实现抛出后的建议。

语法:

@AfterThrowing(PointCut="execution(expression) ", throwing="name")

其中:

PointCut: 它选择一个函数。

execution(expression): 它是要应用建议的表达式。

throwing: 要返回的异常的名称。

让我们在应用程序中实现抛出后的建议。

Spring Boot抛出后建议示例

在这一节中,我们将使用前面的示例。您可以下载项目或对前面的示例进行一些修改。

Spring Boot抛出后建议示例

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

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

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

步骤4:添加Spring Web依赖项。

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

步骤6:提取下载的jar文件。

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

File -> Import -> Existing Maven Projects -> Next -> 浏览文件夹aop-after-throwing-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

    <?xml version="1.0" encoding="UTF-8"?>  
    <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-throwing-advice-example</artifactId>  
    <version>0.0.1-SNAPSHOT</version>  
    <packaging>jar</packaging>  
    <name>aop-after-throwing-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-aop</artifactId>  
    </dependency>  
    <dependency>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-starter-test</artifactId>  
    <scope>test</scope>  
    </dependency>  
    </dependencies>  
    <build>  
    <plugins>  
    <plugin>  
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-maven-plugin</artifactId>  
    </plugin>  
    </plugins>  
    </build>  
    </project>  

步骤9:在src/main/java文件夹中创建一个名为cn.javatiku.model的包。

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

在Account类中,执行以下操作:

  • 定义了两个类型为String的变量accountNumber和accountType。
  • 右键单击文件->Source->Generate Constructor using Fields
  • 生成Getter方法。
  • 右键单击文件->Source->Generate Getters and Setters -> 选择Getters -> Generate
  • 生成一个toString()方法。
  • 右键单击文件->Source->Generate toString()...

Account.java

package cn.javatiku.model;  
public class Account   
{  
private String accountNumber;  
private String accountType;  
public Account(String accountNumber, String accountType)   
{  
super();  
this.accountNumber = accountNumber;  
this.accountType = accountType;  
}  
public String getAccountType()   
{  
return accountType;  
}  
public String getAccountNumber()   
{  
return accountNumber;  
}  
@Override  
public String toString()  
{  
return "Account [accountNumber=" + accountNumber+ ", accountType=" + accountType + "]";  
}  
}  

步骤11:在包cn.javatiku.service.impl中创建另一个名为AccountServiceImpl的类。

在这个类中,我们定义了账户服务。在这个类中,我们定义了一个账户服务。

AccountServiceImpl.java

package cn.javatiku.service.impl;  
import java.util.HashMap;  
import java.util.Map;  
import java.util.Map.Entry;  
import java.util.Set;  
import org.springframework.stereotype.Service;  
import cn.javatiku.model.Account;  
@Service  
public class AccountServiceImpl implements AccountService   
{  
//storing account detail in the HashMap  
private static Map<String,Account> map = null;  
static  
{  
map = new HashMap<>();  
//adding account detail in the map  
map.put("M4546779", new Account("10441117000", "Saving Account"));  
map.put("K2434567", new Account("10863554577", "Current Account"));  
}  
@Override  
public Account getAccountByCustomerId(String customerId) throws Exception  
{  
if(customerId ==null)  
{  
throw new Exception("Invalid! Customer Id");  
}  
Account account= null;  
Set<Entry<String, Account>> entrySet = map.entrySet();  
for (Entry<String, Account> entry : entrySet)   
{  
if(entry.getKey().equals(customerId))  
{  
account= entry.getValue();  
}  
}  
return account;  
}  
}  

步骤12:在包cn.javatiku.service.impl中创建一个名为AccountService的接口。

AccountService.java

ppackage cn.javatiku.service.impl;  
import cn.javatiku.model.Account;  
//creating interface that throws exception if the customer id not found   
public interface AccountService   
{  
public abstract Account getAccountByCustomerId(String customerId)  
throws Exception;  
}  

第14步:创建一个名为cn.javatiku.aspect的包。

第15步:在包cn.javatiku.aspect中创建一个名为AccountAspect的类。

在这个类中,我们通过使用@AfterThrowing注解实现了抛出异常后的advice。我们还定义了一个afterThrowingAdvice()方法。

注意:在throwing属性中定义的名称(ex)必须与advice方法中的参数名对应,否则advice将不会运行。

AccountAspect.java

package cn.javatiku.aspect;  
import org.aspectj.lang.JoinPoint;  
import org.aspectj.lang.annotation.AfterThrowing;  
import org.aspectj.lang.annotation.Aspect;  
import org.springframework.stereotype.Component;  
@Aspect  
@Component  
public class AccountAspect   
{  
//implementing after throwing advice      
@AfterThrowing(value="execution(* cn.javatiku.service.impl.AccountServiceImpl.*(..))",throwing="ex")  
public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex)  
{  
System.out.println("After Throwing exception in method:"+joinPoint.getSignature());  
System.out.println("Exception is:"+ex.getMessage());  
}     
}  

第16步:打开AopAfterThrowingAdviceExampleApplication.java文件,并添加@EnableAspectJAutoProxy注解。

@EnableAspectJAutoProxy注解启用了对标记有@Aspect注解的组件的支持。它与xml配置中的< aop:aspectj-autoproxy/>标签类似。

我们使用了@EnableAspectJAutoProxy注解的proxyTargetClass属性。proxyTargetClass=true允许我们使用CGLIB(Code Generation Library)代理,而不是默认的基于接口的JDK代理方法。

ConfigurableApplicationContext是一个接口,提供了配置应用程序上下文的功能,除了ApplicationContext中的客户端方法。

AopAfterThrowingAdviceExampleApplication.java

package cn.javatiku;  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.context.ConfigurableApplicationContext;  
import org.springframework.context.annotation.EnableAspectJAutoProxy;  
import cn.javatiku.model.Account;  
import cn.javatiku.service.impl.AccountService;  
import cn.javatiku.service.impl.AccountServiceImpl;  
@SpringBootApplication  
//@EnableAspectJAutoProxy annotation enables support for handling the components marked with @Aspect annotation. It is similar to tag in the xml configuration.  
@EnableAspectJAutoProxy(proxyTargetClass=true)  
public class AopAfterThrowingAdviceExampleApplication  
{  
public static void main(String[] args)    
{  
ConfigurableApplicationContext ac = SpringApplication.run(AopAfterThrowingAdviceExampleApplication.class, args);  
//Fetching the account object from the application context  
AccountService accountService = ac.getBean("accountServiceImpl", AccountServiceImpl.class);  
Account account;  
try   
{  
//generating exception  
account = accountService.getAccountByCustomerId(null);  
if(account != null)  
System.out.println(account.getAccountNumber()+"\t"+account.getAccountType());  
}   
catch (Exception e)   
{  
System.out.println(e.getMessage());  
e.printStackTrace();  
}  
}  
}  

创建了所有的类和包后,项目目录如下所示:

7e8a63848e7b28ceb486ee50b2e8b79.png

第17步:打开AopAfterThrowingAdviceExampleApplication.java文件,并将其运行为Java应用程序。它显示的输出如下所示:
ba1e0f4be6b72cc0553242854c7ef74.png

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