为什么我的方面与已经注释@Transational的方法相匹配?

时间:2015-11-19 17:11:13

标签: java spring aop aspectj spring-annotations

我创建了一个简单的注释(@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

Spring Jira SPR-6083

由于使用 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>

0 个答案:

没有答案