为什么没有为Jersey控制器检测到我的Aspect(使用自定义注释)?

我想在Jersey控制器上创建一个Aspect来衡量服务执行的时间。 我正在与我的切入点作斗争,因为它没有被检测到,我的方面永远不会被启动。

我尝试过使用大量的切入点,例如:

execution(@Monitor * *.*(..)) execution(public * *(..)) change the order of @Aspect and @Component Added a pointcut like this: @Pointcut("execution(@Monitor * *.*(..))") public void monitorRequestTargets(){} @Around("monitorRequestTargets()") Tried using AOP and CGLIB  Also tried changing the order of configuration in context.xml 

Eclipse检测到我的方法正在建议我的方法,但它不会在运行时执行。 你能否给我一些提示,说明为什么没有创建方面或切入点没有启动?

我的代码如下。

的context.xml

          

我的MonitorAspect

 @Component @Aspect public class MonitorAspect { private static final Logger logger = LoggerFactory.getLogger(MonitorAspect.class); @Around("@annotation(com.mypackage.Monitor)") public void logTimeUsage(ProceedingJoinPoint joinPoint) throws Throwable { // Store executing method String method = joinPoint.getSignature().getName(); // Track time long startTime = System.currentTimeMillis(); joinPoint.proceed(); long endTime = System.currentTimeMillis(); long duration = endTime - startTime; // Log time consumed by executing method logger.info(method + ": " + duration); } } 

我的Monitor自定义注释是

 @Target(value = {ElementType.METHOD}) @Retention(value = RetentionPolicy.RUNTIME) public @interface Monitor { } 

我想要使​​用方面的控制器:

  @Monitor @POST @Consumes("application/json") @Produces("application/json") @Path("/{tkn}/test/") public Response test( @Context HttpServletRequest httpReq, @Context UriInfo uri, String enrollReqJson ) { Thread.sleep(1000); // Implementation is not important } 

我的pom.xml

   org.springframework spring-context ${org.springframework-version}    commons-logging commons-logging     org.springframework spring-orm ${org.springframework-version}   org.springframework spring-tx ${org.springframework-version}   org.springframework spring-webmvc ${org.springframework-version}   org.springframework spring-orm ${org.springframework-version}    com.sun.jersey.contribs jersey-spring 1.14   org.springframework spring-aop   org.springframework spring   org.springframework spring-core   org.springframework spring-web   org.springframework spring-beans   org.springframework spring-context     com.sun.jersey jersey-bundle 1.8   com.sun.jersey.contribs jersey-multipart 1.8    org.aspectj aspectjrt ${org.aspectj-version}   org.springframework spring-aop ${org.springframework-version}   org.aspectj aspectjweaver ${org.aspectj-version}  

看起来我遇到了同样的问题。 根据您提供的内容,看起来您在Spring上创建的对象上使用Spring AOP(可能是Jersey创建控制器类实例),因此建议未应用。 Eclipse说它被建议,但这只适用于由Spring创建的控制器实例。 您实际使用的是Jersey(或您使用的任何提供商)创建的那些,不建议使用。

我花了很多时间试图让Jersey使用Spring创建控制器实例(包括一些声称能够做到这一点的插件),但从来没有让它工作。 我能够直接使用AspectJ而不是Spring AOP来实现它。 这不是很难,除了弄清楚如何让弹簧注入方面。

添加:

注释保持不变。 您只需要从spring.xml中删除AOP内容,并在META-INF中创建一个aop.xml文件。 这是我的样子:

        

您可以将Spring AOP保留为弹簧加载的类。 您只需要为在spring之外创建的类(如jax的控制器)执行此操作。

我真的不懂一点黑魔法。 如果你需要使用spring注入你自己的方面,那么你需要在spring.xml中声明它,如下所示:

   

请注意,我的方面没有名为aspectOf的方法。 显然是由AspectJ添加的。 这就是它的全部内容。

我发现为什么我的方面不适用于Jersey,因为我不得不使用织布机来处理这个特殊情况。

在配置了aspectj-maven-plugin来编织我的方面之后,一切都运行成功。

配置编织器的完整细节可以在这个答案中找到: Spring + AspectJ使用aspectj-maven-plugin编织java 8

 compile 'org.aspectj:aspectjtools:1.8.1' compile 'org.aspectj:aspectjrt:1.8.1' 

做注释

 @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface ParmsAudit { String action(); } 

方面类

 @Aspect public class AuditAspect { @Before(value="execution(@uk.co.billcomer.audit.ParmsAudit * *(..)) && @annotation(parmsAudit)", argNames="parmsAudit") public void logTheAuditActivity(JoinPoint aPoint, ParmsAudit parmsAudit) { String userName = getUserName(); mlogger.info("Parms Auditing User Name: " + userName); mlogger.info("auditType:" + parmsAudit.auditType().getDescription()); String arguments = getArgs(aPoint.getArgs()); if (arguments.length() > 0) { mlogger.info("args-" + arguments); } } private String getArgs(Object[] args) { String arguments = ""; int argCount = 0; for (Object object : args) { if (argCount > 0) { arguments += ", "; } arguments += "arg[" + ++argCount + "]=" + "[" + object + "]"; } return arguments; } private String getUserName() { try { return SecurityContextHolder.getContext().getAuthentication().getName(); } catch (NullPointerException npe) { return "Unknown User"; } } } 

这是很好的链接http://billcomer.blogspot.in/2011/07/auditing-using-aop-and-annotations-in.html