我创建了一个像
这样的AspectJ拦截器@Aspect
public class RequestSpecificServiceAspect {
@Pointcut("execution( * com.mycompany.c.d.doesTreatmentEqualsAndTrigger(..))")
private void callInterceptor(){}
@Before("callInterceptor()")
public void getCallStack(){
StackTraceElement[] callingStack = Thread.currentThread().getStackTrace();
PopulateServiceDependentMap populateServiceDependentMap = new PopulateServiceDependentMap();
populateServiceDependentMap.populateMap(callingStack, "ServiceName");
}
}
这个工作得很好,因为这是一个试用代码,我现在用我想要的实际拦截器替换它,就像这样
@Pointcut("execution( * mycompany.f.g.findPluginForRequest(..)) && args(request)")
private void actualInterceptor(BSFBatchRequest request){}
@Before("actualInterceptor(request)")
public void getBSFCall(BSFBatchRequest request){
StackTraceElement[] callingStack = Thread.currentThread().getStackTrace();
PopulateServiceDependentMap populateServiceDependentMap = new PopulateServiceDependentMap();
populateServiceDependentMap.populateMap(callingStack, request);
}
但是现在我的拦截器没有拦截对findPluginForRequest()
函数的调用。
为什么会发生这种情况?我该如何解决?
这是我的spring配置文件(.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
default-autowire="no">
<context:annotation-config/>
<aop:aspectj-autoproxy/>
<bean name="com.dpx.dependencyGraphFactory" class="com.mycompany.dpx.dependencytree.ModuleToModuleDependencyGraphFactory"></bean>
<bean name="com.dpx.serviceInterceptor" class="com.mycompany.dpx.dependencytree.RequestSpecificServiceAspect"/>
</beans>
findPluginForRequest()
的签名是private AllPurposeCache<BSFBatchRequest, BSFReply> findPluginForRequest(final BSFBatchRequest request)
。我尝试将切入点更改为
@Pointcut("execution(private * mycompany.f.g.findPluginForRequest(..)) && args(request)")
private void actualInterceptor(BSFBatchRequest request){}
但它仍然不起作用。
答案 0 :(得分:1)
既然您最终共享了方法签名,我可以回答您的问题:
private AllPurposeCache<BSFBatchRequest, BSFReply> findPluginForRequest(
final BSFBatchRequest request
)
Spring AOP没有AspectJ那么强大,因为它不直接编织字节码,而是基于通过JDK或CGLIB创建/使用动态代理。动态代理只是实现接口的子类或类。因此,它们只覆盖公共方法。你的方法是私有的,因此Spring AOP不能拦截它。这在Spring AOP manual:
中有记录由于Spring的AOP框架基于代理的特性,根据定义,受保护的方法既不是针对JDK代理(这不适用),也不针对CGLIB代理(这在技术上可行,但不建议用于AOP)目的)。因此,任何给定的切入点都只能与公共方法匹配! 如果您的拦截需要包括受保护/私有方法甚至构造函数,请考虑使用Spring驱动的本机AspectJ编织而不是Spring的基于代理的AOP框架。这构成了具有不同特征的不同AOP使用模式,因此在做出决定之前一定要先熟悉编织。
为了使其正常工作,请将方法设为公共或切换到AspectJ。
P.S。:这可能更容易,更快。请了解how to ask a question on SO以及如何提供minimal, complete, and verifiable example。谢谢。
答案 1 :(得分:0)
对我而言看起来不错,但我不确定你是否错过了@Aspect
。另一种方法是在单一位置组合切入点和建议。为了避免包名中的任何错误,我将e.f.g.findPluginForRequest
替换为findPluginForRequest
。一旦确定包名
@Aspect
public class LoggingAspect {
@Before("execution(* findPluginForRequest(..))&& args(request)")
public void beforeeAdvice(BSFBatchRequest request ){
}
}