【发布时间】:2014-01-21 23:51:27
【问题描述】:
我想在 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
<aop:aspectj-autoproxy proxy-target-class="true"/>
Also tried changing the order of configuration in context.xml
Eclipse 检测到我的方法正在由我的方面提供建议,但它没有在运行时执行。你能给我任何关于为什么没有创建方面或没有启动切入点的提示吗?
我的代码如下。
Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.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">
<!-- Enables the Spring MVC @Controller -->
<annotation-driven />
<!-- Enables AspectJ -->
<aop:aspectj-autoproxy />
<!-- .....more definitions -->
<context:component-scan base-package="com.mypackage" />
</beans:beans>
我的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
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- Jersey / Spring -->
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-spring</artifactId>
<version>1.14</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-bundle</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-multipart</artifactId>
<version>1.8</version>
</dependency>
<!-- Spring AOP / AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
【问题讨论】:
-
你的控制器在 com.mypackage 包中吗?
-
Kyle 提到的任何内容以及 @Around(value = "@annotation(com.mypackage.Monitor)")。试试这个。在组件扫描期间是否也扫描了您的 Aspect?
-
另外,一个 around Advice 应该返回一个 Object,它不能是 void
-
让我们看看你的完整控制器类。
-
@Hrishikesh,如何检查我的方面是否在组件扫描时被扫描?
标签: java jersey aop aspectj spring-aop