我正在学习 AOP spring 并尝试一些示例。关于@AfterReturning,我的理解是只有当目标成功返回并且匹配切入点时才会调用该方法。然而,在我的例子中,如下所示,我有一个切入点,它定义了所有只返回一个字符串的方法,但它调用了所有的 void 方法以及返回一个字符串的方法。
我的建议:
@AfterReturning(value= "execution(* com.aop..CustomerServiceImpl.*(..))",
returning= "string")
public void returnStringPointcut(JoinPoint joinPoint,String string){
System.out.println("logAfter() is running!");
System.out.println("String : " + string);
System.out.println("hijacked : " + joinPoint.getSignature().getName());
System.out.println("******");
}
请在下面找到我的 Impl 类:
public void addCustomer() {
// TODO Auto-generated method stub
}
public String getCustomer() {
// TODO Auto-generated method stub
return "string";
}
public boolean deleteCustomer() {
// TODO Auto-generated method stub
return false;
}
public void addCustomerAppended() {
// TODO Auto-generated method stub
}
public void deleteCustomerVoid() {
// TODO Auto-generated method stub
//return false;
}
请在下面找到我的 MainApp 类:
public class App {
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext(
"Spring-Customer.xml");
CustomerService cs = context.getBean("customerBo", CustomerService.class);
cs.addCustomer();
cs.addCustomerAppended();
cs.deleteCustomer();
cs.deleteCustomerVoid();
cs.getCustomer();
}
}
我原以为只有 getCustomer() 会被调用,因为它是唯一一个返回字符串的函数,但是当我运行应用程序时,我在控制台中得到了以下输出:
logAfter() is running!
String : null
hijacked : addCustomer
******
logAfter() is running!
String : null
hijacked : addCustomerAppended
******
logAfter() is running!
String : null
hijacked : deleteCustomerVoid
******
logAfter() is running!
String : string
hijacked : getCustomer
******
请在下面找到我的 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>com.aop.spring</groupId>
<artifactId>SpringAopOnly</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>SpringAopOnly</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>3.0.5.RELEASE</spring.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>test</scope>
</dependency>
<!-- Spring 3 dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring AOP -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.6.11</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.6.11</version>
</dependency>
</dependencies>
</project>
请在下面找到我的配置文件:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<!-- <aop:aspectj-autoproxy /> -->
<aop:aspectj-autoproxy>
<aop:include name ="logAspect" />
</aop:aspectj-autoproxy>
<bean id="customerBo" class="com.aop.impl.CustomerServiceImpl" />
<!-- Aspect -->
<bean id="logAspect" class="com.aop.aspect.CustomerAspect" />
</beans>
知道它为什么调用 void 方法吗?
我还尝试将 afterReturning 从字符串更改为 boolean 值,然后我得到预期的结果,即只调用 deleteCustomer,因为它返回 boolean 值。
非常感谢您的回复。
最佳答案
返回
参数只指定
The name of the argument in the advice signature to bind the returned value to
你的实际切入点
@AfterReturning(value= "execution(* com.aop..CustomerServiceImpl.*(..))",
returning= "string")
正在指定
execution(* com.aop..CustomerServiceImpl.*(..))
其中 *
匹配所有返回类型。
你应该把它改成
execution(java.lang.String com.aop..CustomerServiceImpl.*(..))
如果您只需要声明为返回 String
的方法。
注解 value
表达式中的返回类型和方法参数类型都在建议哪些方法方面发挥作用。例如
@AfterReturning(value = "execution(String com.aop..CustomerServiceImpl.*(..))", returning = "random")
public void returnStringPointcut(JoinPoint joinPoint, Integer random) {
不会匹配任何东西。
附带说明一下,您应该考虑升级您的 Spring 和 aspectj 版本。我认为其中很多问题要么已解决,要么整个库更加稳定。
关于java - AOP Spring @AfterReturning 没有按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20726737/