【问题标题】:Spring AOP Aspect not executingSpring AOP 方面未执行
【发布时间】:2011-09-20 20:46:50
【问题描述】:

我一直试图弄清楚为什么我的简单方面没有得到执行。我查看了类似问题的答案,但仍然无法正常工作。

我的意图是将使用自定义注释注释的方法的执行与 AOP 建议相结合,该建议将跟踪方法运行所需的时间。当我运行测试时,我看到了方法的输出,但建议没有运行(我希望它记录一些输出)。

这是 Aspect 类:

@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) {
        }
    }
}

弹簧配置:

<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
...

非常感谢任何建议。

【问题讨论】:

    标签: java aop aspectj spring-aop aspects


    【解决方案1】:

    所以我稍微摆弄了一下,让它开始工作。我修改了方面如下:

    @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"/>
    

    【讨论】:

      猜你喜欢
      • 2013-01-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多