我创建了一个简单的注释(@ProfilePerformace),它结合了AspectJ的魔力,应该测量任何方法或类的注释性能并将结果打印到Slf4j。它接缝适用于所有未注释的方法,但不适用于具有另一个注释的方法,例如@Transaction或@PostContruct。任何关于为什么会发生这种情况的想法都会很棒。
我使用Spring 4.2.2和AsjectJWeaver:1.8.7由Spring-Aspects引入。
注释
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
@Documented
public @interface ProfilePerformance {
}
方面
@Aspect
@Component
public class ProfilePerformanceAspect {
private static final Logger log = LoggerFactory.getLogger(ProfilePerformanceAspect.class);
@Around(value = "@within(ProfilePerformance) || @annotation(ProfilePerformance)")
public Object profile(ProceedingJoinPoint pjp) throws Throwable {
MethodSignature signature = (MethodSignature) pjp.getSignature();
String methodName = signature.getMethod().getName();
StopWatch stopWatch = new StopWatch(methodName);
stopWatch.start(methodName);
Object output = pjp.proceed();
stopWatch.stop();
log.info("Class [{}] Method [{}] Execution Time [{}ms]", pjp.getTarget().getClass().getSimpleName(), methodName,
stopWatch.getTotalTimeMillis());
return output;
}
有效的代码示例:
@ProfilePerformance
public void delete(Item item) {...}
不起作用的方法示例:
@Transactional
@ProfilePerformance
public void update() {...}
修改
经过多次挖掘后,我在Spring论坛上找到了这两个帖子,指出了同样的问题。
Using-multiple-aspects-annotations-at-the-same-time-requires-annotating-interfaces
由于使用 aop:aspectj-autoproxy / 应用我的注释(@ProfilePerformance)并应用了@Transactional,因此可能会出现同时应用这两个注释的问题使用 tx:annotation-driven 。本质上,当我的注释被应用时,该方法已被代理以便应用@Transactional,因此我的Aspect不匹配。
我已经应用了上面链接中发布的工作,但我真的很想知道我是否正确地做到这一点,因为这种方法闻起来有点滑稽。
解决方法
<!-- Use this instead of "tx:annotation-driven" so that we can register other Aspects on @Transactional methods. -->
<bean class="org.springframework.transaction.interceptor.TransactionAttributeSourceAdvisor">
<property name="transactionInterceptor">
<bean class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
</property>