1.首先写了一个环绕通知
package com.nstc.aims.interceptor;
import java.io.PrintStream;
import java.lang.reflect.Method;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class EntityHistoryInterceptor
implements MethodInterceptor
{
public Object invoke(MethodInvocation methodInvocation)
throws Throwable
{
Method method = methodInvocation.getMethod();
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
System.out.println(methodInvocation.toString());
System.out.println(Integer.toHexString(methodInvocation.hashCode()));
System.out.println(method.getDeclaringClass());
System.out.println(method.toString());
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
String methodName = method.toGenericString();
String xmlName = methodName.substring(methodName.lastIndexOf(" ") + 1);
System.out.println(xmlName);
Object object = methodInvocation.proceed();
return object;
}
}
配置文件,由于公司使用的是Spring1.2.9,配置文件没有aop标签。:
AIMS.accountBasicSetService
AIMS.accountService
AIMS.associateBankService
AIMS.associateBankService
AIMS.accountBalanceService
AIMS.accountRecordService
AIMS.bizFlowService
AIMS.bp3CallBackService
AIMS.bp3ConnectService
AIMS.commonService
AIMS.umFormService
AIMS.accountSynchroService
AIMS.cfbRemoteService
AIMS.attachService
AIMS.recordMouldService
AIMS.transactionInterceptor //这个是公司原有的配置
AIMS.entityHistoryAdvisor //这个是我加的切面
执行结果如图:
原因是:
Proxy$285代理了Bean,Proxy$286代理了Proxy$285,我写的切面代理了Proxy$286,
所以导致执行了三次。
考虑是配置文件使用的spring的bean有问题,于是换了一种实现方式:
结果和一开始一样,也是被代理了三次,改变位置也没办法。
考虑不使用环绕通知,使用后置通知,并且把切面放到最上面试一下。如果不行的话,就要考虑在方法中判断target了。
Interceptor:
public class EntityHistoryAfterAdvice implements AfterReturningAdvice {
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@");
System.out.println(target);
}
}
配置文件
AIMS.accountBasicSetService
AIMS.accountService
AIMS.associateBankService
AIMS.associateBankService
AIMS.accountBalanceService
AIMS.accountRecordService
AIMS.bizFlowService
AIMS.bp3CallBackService
AIMS.bp3ConnectService
AIMS.commonService
AIMS.umFormService
AIMS.accountSynchroService
AIMS.cfbRemoteService
AIMS.attachService
AIMS.recordMouldService
AIMS.entityHistoryAdvisor
AIMS.transactionInterceptor
.*RecordMouldService.*
结果:
执行了6次,分析应该是这样的。应该执行5次,最后多的那一次是最后的代理类的顺序导致。
应当把后置通知放到最后,执行了5次。
后面考虑是实现的接口不对:
换成了Cglib的接口MethodInterception,结果直接报错。
代理那个类的方法在本模块没有找到,有可能是公司框架的封装。无权修改。
实在没办法了,只有去invoke方法中判断target了。
最终代码如下:
package com.nstc.aims.interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ReflectiveMethodInvocation;
import com.nstc.aims.service.impl.RecordMouldServiceImpl;
/**
* Title: EntityHistoryAroundAdvice.java
*
* Description: 环绕通知
*
* Company: 北京九恒星科技股份有限公司
*
* @author luhao
*
* @since:2019年6月5日 上午11:59:46
*
*/
public class EntityHistoryAroundAdvice implements MethodInterceptor{
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
ReflectiveMethodInvocation reflectiveMethodInvocation = (ReflectiveMethodInvocation) methodInvocation;
boolean isRealClass = reflectiveMethodInvocation.getThis().getClass() == RecordMouldServiceImpl.class;
if(!isRealClass) {
return methodInvocation.proceed();
}
Object[] args = reflectiveMethodInvocation.getArguments();//方法参数
Object object = methodInvocation.proceed();//方法结果
return object;
}
}
AIMS.accountBasicSetService
AIMS.accountService
AIMS.associateBankService
AIMS.associateBankService
AIMS.accountBalanceService
AIMS.accountRecordService
AIMS.bizFlowService
AIMS.bp3CallBackService
AIMS.bp3ConnectService
AIMS.commonService
AIMS.umFormService
AIMS.accountSynchroService
AIMS.cfbRemoteService
AIMS.attachService
AIMS.recordMouldService
AIMS.transactionInterceptor
AIMS.entityHistoryAdvisor
.*RecordMouldService.*