2011-06-23 52 views
1

我一直在試圖找出爲什麼我的簡單方面沒有得到執行。我查看了類似問題的答案,但仍然無法實現。春季AOP方面沒有執行

我的意圖是用一個AOP建議來包裝一個用自定義註釋註解的方法的執行,這個AOP建議將跟蹤該方法需要運行多長時間。當我運行我的測試時,我看到了方法的輸出,但通知沒有運行(我期待它記錄一些輸出)。

這裏的看點類:

@Aspect 
class LatencyProfiler { 

    private LatencyTrackerFactory factory = LatencyTrackerFactory.NOOP; 

    @Pointcut(value="execution(@ProfileLatency * *(..)) && @annotation(annotation)", argNames="annotation") 
    public void profiled(ProfileLatency annotation) {} 

    @Around(value="profiled(annotation)", argNames="pjp,annotation") 
    public Object profile(ProceedingJoinPoint pjp, ProfileLatency annotation) throws Throwable { 

     ILatencyTracker tracker; 

     try { 
      tracker = factory.create(annotation.trackerName(), annotation.trackerNameSuffix()); 
     } catch (ConfigException e) { 
      throw new RuntimeException(e); 
     } 

     tracker.begin(); 
     Object ret = pjp.proceed(); 
     tracker.end(null); 

     return ret; 
    } 

    @Optional 
    public void setFactory(LatencyTrackerFactory factory) { 
     this.factory = factory; 
    } 
} 

其次譯註:

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.METHOD) 
public @interface ProfileLatency { 
    String trackerName(); 
    String trackerNameSuffix() default"[unassigned]"; 
} 

其次是測試類:

public class Test { 
    private static final Log LOG = LogFactory.getLog(Test.class); 

    @PostConstruct 
    public void init() { 
     Executors.newSingleThreadScheduledExecutor().schedule(new Runnable() { 
        @Override 
        public void run() { 
         for(int i = 0; i < 60; i++) { 
          foo(); 
          LOG.info("HERE"); 
         } 
        } 
       }, 2000, TimeUnit.MILLISECONDS); 

    } 

    @ProfileLatency(trackerName = "latency", trackerNameSuffix = "s") 
    public void foo() { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ignored) { 
     } 
    } 
} 

Spring配置:

<context:annotation-config/> 
<aop:aspectj-autoproxy> 
    <aop:include name="latencyProfileAspect"/> 
</aop:aspectj-autoproxy> 

<bean 
    id = "latencyLogger" 
    class = "util.logging.LatencyLogger" 
/> 

<bean 
    id = "trackerFactory" 
    class = "util.latency.LatencyTrackerFactoryImpl"> 
    <constructor-arg value = "config/latency-config.xml"/> 
    <constructor-arg ref = "latencyLogger"/> 
</bean> 

<bean 
    id   = "latencyProfileAspect" 
    class   = "util.latency.aop.LatencyProfiler" 
    p:factory-ref = "trackerFactory" 
/> 

<bean id = "test" class="util.Test"/> 

最後測試的輸出:

21:20:37,930 INFO main/SpringMain - Ready. 
21:20:40,928 INFO pool-4-thread-1/Test - HERE 
21:20:41,927 INFO pool-4-thread-1/Test - HERE 
21:20:42,926 INFO pool-4-thread-1/Test - HERE 
21:20:43,925 INFO pool-4-thread-1/Test - HERE 
21:20:44,924 INFO pool-4-thread-1/Test - HERE 
... 

任何意見是極大的讚賞。

回答

2

所以我擺弄這一點,並得到它的工作。我改性方面如下:

@Aspect 
public class LatencyProfiler { 

    private static final Log LOG = LogFactory.getLog(LatencyProfiler.class); 

    @Around("@annotation(annotation)") 
    public Object profile(ProceedingJoinPoint pjp, ProfileLatency annotation) throws Throwable { 

     ILatencyTracker tracker = ILatencyTracker.NOOP; 

     try { 
      tracker = StaticLatencyTrackerFactory.getTracker(annotation.trackerName(), annotation.trackerNameSuffix()); 
     } catch (Exception e) { 
      LOG.error(e); 
     } 

     LatencyContext ctx = tracker.beginContext(); 
     Object ret = pjp.proceed(); 
     ctx.end(); 

     return ret; 
    } 

    /* 
    * special purpose factory method 
    */ 
    public static LatencyProfiler aspectOf() { 
     return MyAspectHolder.instance; 
    } 

    /** 
    * private class holding the singleton 
    */ 
    private static class MyAspectHolder { 
     static final LatencyProfiler instance = new LatencyProfiler(); 
    } 
} 

我也改變了彈簧配置爲:

<context:annotation-config/> 
<aop:aspectj-autoproxy proxy-target-class="true"/> 

<bean 
    id    = "latencyProfileAspect" 
    class   = "util.latency.aop.LatencyProfiler" 
    factory-method = "aspectOf" 
/> 

<bean id = "test" class="util.Test"/>