- 错误信息
java.lang.StackOverflowError
at org.springframework.aop.framework.AdvisedSupport$MethodCacheKey.hashCode(AdvisedSupport.java:603)
at java.util.concurrent.ConcurrentHashMap.hash(ConcurrentHashMap.java:333)
at java.util.concurrent.ConcurrentHashMap.get(ConcurrentHashMap.java:988)
at
.....(错误的信息搞到一千多行,截取部分 )
- 项目的目录结构
- 各个类的代码
1.Advice.java
package com.d.aop_2;
public class Advice {
public void before(){
System.out.println("前");
}
public void after(){
System.out.println("后");
}
}
- UserServiceImpl.java
package com.d.aop_2;
public class UserServiceImpl implements UserService {
public void addUser(){
System.out.println("addUser()");
}
public void deleteUser(){
System.out.println("deleteUser()");
}
}
- MyAspect.java
package com.d.aop_2;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAspect implements MethodInterceptor {
public Advice advice;
public void setAdvice(Advice advice) {
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
advice.before();
Object obj = mi.proceed(); // 执行目标方法,类似于 method.invoke(service,args);
advice.after();
return obj;
}
}
- bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 创建目标类 -->
<bean id="userService" class="com.d.aop_2.UserServiceImpl"></bean>
<bean id="advice" class="com.d.aop_2.Advice"></bean>
<!-- 创建切面类 -->
<bean id="aspect" class="com.d.aop_2.MyAspect">
<property name="advice" ref="advice"></property>
</bean>
<aop:config>
<!-- 表示切入点为该包下所有的方法 -->
<aop:pointcut expression="execution(* com.d.aop_2.*.*(..))" id="pointCut"/>
<aop:advisor advice-ref="aspect" pointcut-ref="pointCut" />
</aop:config>
</beans>
- 分析:通过以上的配置,会出现 java.lang.StackOverflowError错误信息
原因是在 :
<aop:pointcut expression="execution(* com.d.aop_2.*.*(..))" id="pointCut"/>
因为此时,Advice 中的方法也相当于连接点。此处如果在
···
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
advice.before();
Object obj = mi.proceed(); // 执行目标方法,类似于 method.invoke(service,args);
advice.after();
return obj;
}
···
这个方法中,又调用连接点的方法。而连接点又会调连接点,那么就会在 before()这个方法中无限的递归调用下去,而没有出口,所以会报错。
- 解决办法: 将 Advice 中的方法从“连接点”中去除,那么它就不是连接点,就不会反复调用自己
修改 bean.xml 中的配置如下这一行代码即可
<aop:pointcut expression="execution(* com.d.aop_2.UserServiceImpl.*(..))" id="pointCut"/>