After returning是Spring AOP中的一個(gè)建議,通常在連接點(diǎn)執(zhí)行完成(執(zhí)行)后調(diào)用。如果引發(fā)異常,則不會(huì)調(diào)用。我們可以使用 @AfterReturning 批注在應(yīng)用程序中返回建議后實(shí)施。注解將功能標(biāo)記為要在PointCut覆蓋的方法之前執(zhí)行的建議。
在返回的建議運(yùn)行之后,當(dāng)匹配的方法執(zhí)行正常返回值時(shí),便會(huì)執(zhí)行該建議。我們?cè)趓eturn屬性中定義的名稱必須與advice方法中的參數(shù)名稱相對(duì)應(yīng)。當(dāng)方法返回值時(shí),該值將作為相應(yīng)的參數(shù)值傳遞到通知方法。
讓我們?cè)趹?yīng)用程序中返回通知后實(shí)現(xiàn)。
步驟1: 打開Spring Initializr http://start.spring.io 。
步驟2: 提供 Group 名稱。我們提供了組名 com.nhooo。
步驟3: 提供了 Artifact Id。提供Artifact Id aop-after-returning-advice-example。
步驟4: 添加 Spring Web 依賴項(xiàng)。
步驟5: 點(diǎn)擊 生成按鈕。當(dāng)我們單擊"生成"按鈕時(shí),它將所有規(guī)范包裝在 jar 文件中,并將其下載到本地系統(tǒng)。
步驟6: 提取
第7步: 使用以下步驟導(dǎo)入文件夾:
文件->導(dǎo)入->現(xiàn)有Maven項(xiàng)目->下一步->瀏覽文件夾 aop-returning-advice-example示例->完成。
步驟8: 打開 pom.xml 文件并添加以下 AOP 依賴項(xiàng)。它是使用 Spring AOP 和 AspectJ 進(jìn)行面向方面編程的入門。
<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>com.nhooo</groupId> <artifactId>aop-after-returning-advice-example</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>aop-after-returning-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 文件夾 中創(chuàng)建名稱為 com.nhooo.model 的包。
步驟10: 在包 com.nhooo.model中創(chuàng)建一個(gè)名稱為 Account 的類。
在"Account"類中,執(zhí)行以下操作:
定義了兩個(gè)類型為String的變量 accountNumber 和 accountType 。 右鍵單擊文件->源->使用字段生成構(gòu)造函數(shù) 生成Getters。
右鍵單擊文件-> Source-> Generate Getters和Setters->選擇Getters-> Generate 生成 toString()
右鍵單擊文件->源->生成toString()...
Account.java
package com.nhooo.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: 創(chuàng)建另一個(gè)名為 com.nhooo.service.impl的包。
步驟12: 在此程序包中,創(chuàng)建一個(gè)名稱為 AccountServiceImple的類。
在該類中,我們定義了帳戶服務(wù)。
AccountServiceImpl。 Java
package com.nhooo.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 com.nhooo.model.Account;
@Service
public class AccountServiceImpl implements AccountService
{
//在 HashMap 中存儲(chǔ)帳戶細(xì)節(jié)
private static Map<String,Account> map = null;
static
{
map = new HashMap<>();
//在map中添加帳戶詳細(xì)信息
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;
}
}
步驟13: 在 com.nhooo.service.impl。包中創(chuàng)建名稱為 AccountService 的接口。
AccountService.java
package com.nhooo.service.impl;
import com.nhooo.model.Account;
//正在創(chuàng)建一個(gè)接口,如果找不到客戶id則引發(fā)異常
public interface AccountService
{
public abstract Account getAccountByCustomerId(String customerId) throws Exception;
}
步驟14: 創(chuàng)建名稱為 com.nhooo.aspect的包。
步驟15: 在包 com.nhooo.aspect 中創(chuàng)建一個(gè)名稱為 AccountAspect 的類。
在該類中,我們使用注解 @AfterReturning。 我們還定義了 afterReturningAdvice()方法。
注意: 我們?cè)?中定義的name(account) > returning 屬性必須與 advice方法中的參數(shù)名稱相對(duì)應(yīng)。
AccountAspect.java
package com.nhooo.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import com.nhooo.model.Account;
@Aspect
@Component
public class AccountAspect
{
//implementing after returning advice
@AfterReturning(value="execution(* com.nhooo.service.impl.AccountServiceImpl.*(..))",returning="account")
public void afterReturningAdvice(JoinPoint joinPoint, Account account)
{
System.out.println("After Returing method:"+joinPoint.getSignature());
System.out.println(account);
}
}
步驟16: 打開 AopAfterReturningAdviceExampleApplication.java 文件并添加注解 @EnableAspectJAutoProxy。
注解支持處理帶有AspectJ的 @Aspect 批注的組件。它與@Configuration批注一起使用。
我們使用了@EnableAspectJAutoProxy批注的 proxyTargetClass 屬性。屬性 proxyTargetClass = true 允許我們使用 CGLIB (代碼生成庫)代理,而不是默認(rèn)的基于接口的JDK代理方法。
ConfigurableApplicationContext 是一個(gè)接口,除了ApplicationContext中的應(yīng)用程序上下文客戶端方法外,還提供了用于配置應(yīng)用程序上下文的工具。
AopAfterReturningAdviceExampleApplication.java
package com.nhooo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import com.nhooo.model.Account;
import com.nhooo.service.impl.AccountService;
import com.nhooo.service.impl.AccountServiceImpl;
@SpringBootApplication
//@EnableSpectProxy注解支持處理用@Aspect注解標(biāo)記的組件。它類似于xml配置中的標(biāo)記。
@EnableAspectJAutoProxy(proxyTargetClass=true)
public class AopAfterReturningAdviceExampleApplication
{
public static void main(String[] args)
{
ConfigurableApplicationContext ac = SpringApplication.run(AopAfterReturningAdviceExampleApplication.class, args);
//從應(yīng)用程序上下文獲取account對(duì)象
AccountService accountService = ac.getBean("accountServiceImpl", AccountServiceImpl.class);
Account account;
try
{
account = accountService.getAccountByCustomerId("K2434567");
if(account != null)
System.out.println(account.getAccountNumber()+"\t"+account.getAccountType());
}
catch (Exception e)
{
System.out.println(e.getMessage());
}
}
}
創(chuàng)建所有類和包之后,項(xiàng)目目錄如下所示:
步驟17: 打開 AopAfterReturningAdviceExampleApplication.java 文件并將其作為Java應(yīng)用程序運(yùn)行。它顯示輸出,如下所示:
在下一節(jié)中,我們將在提出建議后理解。