Java spring 3.0 aop 切入点格式不正确:期待“名称模式”错误
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3832361/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
spring 3.0 aop Pointcut is not well-formed: expecting 'name pattern' error
提问by user463008
The following is my pointcut and advise declaration
以下是我的切入点和建议声明
//PointCut on A method which takes two parameters and is in a DAO
@Pointcut("execution(backend.repository.QuestionsRepository.AnswerQuestion (..))")
public void answerQuestionPointCut() {}
@Around(
value="web.activity.advisors.UserActivityAdvisor.answerQuestionPointCut()",
argNames="question,answer"
)
// Do something
}
I get the following error
我收到以下错误
Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Pointcut is not well-formed: expecting 'name pattern' at character position 65
execution(backend.repository.QuestionsRepository.AnswerQuestion (..))
^
Am stuck on this, Any pointers
我坚持这一点,任何指针
采纳答案by Sean Patrick Floyd
You are missing the return type:
您缺少返回类型:
@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..))")
and you have to bind the argument names, something like this:
并且您必须绑定参数名称,如下所示:
@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..))
&& args(question, answer)") // wrapped for readability only
Example Solution
示例解决方案
Service Interface:
服务接口:
package foo.bar.service;
public interface Service{
void whack(String thing, Integer thang);
}
Implementation class:
实现类:
package foo.bar.service;
public class DefaultService implements Service{
@Override
public void whack(final String thing, final Integer thang){
System.out.println(
"Inside thing: " + thing + ", inside thang: " + thang
);
}
}
Spring AOP aspect:
Spring AOP方面:
@Aspect
public class ServiceAspect{
@Pointcut("execution(* foo.bar.service.*.*(..))")
public void serviceMethodExecution(){
}
@Around(value = "serviceMethodExecution() && args(param1, param2)")
public void aroundServiceMethodExecution(final ProceedingJoinPoint pjp,
final String param1,
final Integer param2) throws Throwable{
System.out.println("Before thing: " + param1 + ", before thang: "
+ param2);
pjp.proceed();
System.out.println("After thing: " + param1 + ", after thang: "
+ param2);
}
}
Spring Context XML:
Spring 上下文 XML:
<aop:aspectj-autoproxy proxy-target-class="false" />
<bean class="foo.bar.service.DefaultService" />
<bean class="foo.bar.aspects.ServiceAspect" />
Main class for testing:
主要测试类:
Now here's a main method to test the whole process. It starts a Spring ApplicationContext without XML configurationwith the above XML defining the service bean and the aspect (it turns out that the solution without XML only worked because I had AspectJ weaving turned on, I don't know what beans I have to include to enable aspectj-autoproxy, so I now use ClassPathXmlApplicationContext
with this minimal XML):
现在这里有一个主要的方法来测试整个过程。它启动一个没有 XML 配置的 Spring ApplicationContext ,上面的 XML 定义了服务 bean 和方面(事实证明,没有 XML 的解决方案只工作,因为我打开了 AspectJ 编织,我不知道我必须包含哪些 bean启用 aspectj-autoproxy,所以我现在使用ClassPathXmlApplicationContext
这个最小的 XML):
public static void main(final String[] args){
final ApplicationContext applicationContext =
new ClassPathXmlApplicationContext("classpath:/aspectContext.xml");
final Service service = applicationContext.getBean(Service.class);
service.whack("abc", 123);
}
Output:
输出:
Before thing: abc, before thang: 123
Inside thing: abc, inside thang: 123
After thing: abc, after thang: 123
This should get you started. Basically: you need to check that the methods you are intercepting are backed by a service interface if you use JDK proxies (spring default). Read here about Spring AOP proxy mechanisms.
这应该让你开始。基本上:如果您使用 JDK 代理(spring 默认),您需要检查您正在拦截的方法是否由服务接口支持。在此处阅读有关Spring AOP 代理机制的信息。
Note:
笔记:
As you see I bind the method arguments to the aspect, not the pointcut, hence making the pointcut reusable for methods with different argument signatures. But it would also be possible to bind them in the pointcut, like this:
如您所见,我将方法参数绑定到方面,而不是切入点,因此使切入点可重用于具有不同参数签名的方法。但是也可以在切入点中绑定它们,如下所示:
@Pointcut(value = "execution(* foo.bar.service.*.*(..)) && args(a,b)",
argNames = "a,b")
public void serviceMethodExecution(final String a, final Integer b){
}
@Around(value = "serviceMethodExecution(param1, param2)",
argNames = "param1,param2")
public void aroundServiceMethodExecution(final String param1,
final Integer param2,
final ProceedingJoinPoint pjp) throws Throwable{
System.out.println("Before thing: " + param1 + ", before thang: "
+ param2);
pjp.proceed();
System.out.println("After thing: " + param1 + ", after thang: "
+ param2);
}
回答by Mr.Strolling
You should write like this
你应该这样写
@Pointcut("execution(* backend.repository.QuestionsRepository.AnswerQuestion (..))")
pay attention to "... (* backend..."
注意 "... (* backend..."
*
anda space should be used.
*
并且应该使用一个空格。
回答by trinity
Note that you have similar behaviour with the @Before
annotation in org.aspectj.lang.annotation.Before
.
请注意,您有类似行为@Before
的注解org.aspectj.lang.annotation.Before
。
You can use the expression without executionkey word and without a return type:
您可以使用没有执行关键字且没有返回类型的表达式:
@Before("allGetters()")
or with both:
或两者兼而有之:
@Before("execution(public * allGetters())")
but you can not use the execution
keyword without using the return type.
但是您不能在execution
不使用返回类型的情况下使用关键字。