Spring:编译时编织需要@EnableAspectJAutoProxy吗?

时间:2014-03-01 15:09:54

标签: eclipse spring maven caching aspectj

我环顾互联网并找到了一些建议,并尝试了不同的配置,但我完全不确定它是否正常工作。

pom.xml (完整的pom.xml:http://pastebin.com/5Y2qksTH):

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <groupId>org.eclipse.m2e</groupId>
                <artifactId>lifecycle-mapping</artifactId>
                <version>1.0.0</version>
                <configuration>
                    <lifecycleMappingMetadata>
                        <pluginExecutions>
                            <pluginExecution>
                                <pluginExecutionFilter>
                                    <groupId>org.codehaus.mojo</groupId>
                                    <artifactId>aspectj-maven-plugin</artifactId>
                                    <versionRange>[1.0,)</versionRange>
                                    <goals>
                                        <goal>test-compile</goal>
                                        <goal>compile</goal>
                                    </goals>
                                </pluginExecutionFilter>
                                <action>
                                    <execute>
                                        <runOnConfiguration>true</runOnConfiguration>
                                        <runOnIncremental>true</runOnIncremental>
                                    </execute>
                                </action>
                            </pluginExecution>
                        </pluginExecutions>
                    </lifecycleMappingMetadata>
                </configuration>
            </plugin>
        </plugins>
    </pluginManagement>

    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.5</version>
            <configuration>
                <Xlint>warning</Xlint>
                <complianceLevel>1.7</complianceLevel>
                <source>1.7</source>
                <target>1.7</target>
                <encoding>UTF-8</encoding>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring-aspects</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

我添加了

<execute>
    <runOnConfiguration>true</runOnConfiguration>
    <runOnIncremental>true</runOnIncremental>
</execute>

因为在我看来我总是需要在Eclipse中进行Project -> Clean之后才进行Tomcat -> Clean。否则它总是执行我的缓存方法。现在它似乎自动运作。

CacheableConfig.java

@EnableCaching(mode = AdviceMode.ASPECTJ)
public class CacheableConfig implements CachingConfigurer {
    @Override
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("testCache");
    }

    @Override
    public KeyGenerator keyGenerator() {
        return new SimpleKeyGenerator();
    }
}

AppConfig.java

@EnableAspectJAutoProxy
public class AppConfig {}

没有@EnableAspectJAutoProxy它根本不起作用。

MyTestServiceImpl.java

@Service
public class MyTestServiceImpl implements MyTestService {
    @Scheduled(initialDelay=10000, fixedDelay=30000)
    public void a() {
        long time = System.currentTimeMillis();
        System.out.println("START");
        System.out.println("returned: " + b(0));
        System.out.println("returned: " + b(1));
        System.out.println("returned: " + b(0));
        System.out.println("returned: " + b(1));
        System.out.println("returned: " + b(2));
        System.out.println("END: " + (System.currentTimeMillis() - time));
    }

    @Cacheable("testCache")
    public int b(int i) {
        System.out.println("INSIDE CACHED METHOD");
        i++;
        try {
            Thread.sleep(2000);
        } catch(InterruptedException ex) {}
        return i;
    }
}

注意:我只是使用@Scheduled来多次自动调用该方法。

输出:

START
2014-03-01 15:53:25,796 DEBUG    o.s.c.annotation.AnnotationCacheOperationSource: 109 - Adding cacheable method 'b' with attribute: [CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless='']
2014-03-01 15:53:25,797 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
INSIDE CACHED METHOD
returned: 1
2014-03-01 15:53:27,798 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
INSIDE CACHED METHOD
returned: 2
2014-03-01 15:53:29,799 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:53:29,799 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 1
2014-03-01 15:53:29,799 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:53:29,799 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 2
2014-03-01 15:53:29,799 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 2 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
INSIDE CACHED METHOD
returned: 3
END: 6018

START
2014-03-01 15:54:01,801 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:54:01,801 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 1
2014-03-01 15:54:01,801 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:54:01,801 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 2
2014-03-01 15:54:01,801 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:54:01,802 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 0 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 1
2014-03-01 15:54:01,802 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:54:01,802 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 1 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 2
2014-03-01 15:54:01,802 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 2 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
2014-03-01 15:54:01,802 TRACE            o.s.cache.aspectj.AnnotationCacheAspect: 318 - Computed cache key 2 for operation CacheableOperation[public int MyTestServiceImpl.b(int)] caches=[testCache] | key='' | condition='' | unless=''
returned: 3
END: 1

这基本上看起来没问题:

  • a()的第一次调用需要6秒,因为b()会被有效调用3次。
  • a()的第二次调用需要1ms,因为所有内容都来自缓存。
  • 返回值没问题。

问题

  1. 为什么那些TRACE日志Computed cache key x for operation ...总是两次次?在我看来,计算方法被调用了两次?!

  2. 配置好吗?因为我不确定这是否总是按预期工作,特别是因为我有时必须使用Project -> CleanTomcat -> Clean。 (否则它只是忽略了@Cacheable注释和简单的方法)

  3. 谢谢!

1 个答案:

答案 0 :(得分:2)

首先,您当前的设置永远不会与@EnableAspectJAutoProxy一起使用。 Spring AOP使用代理来应用方面。您的@Scheduled在内部调用该方法,因此永远不会通过代理,您将永远不会进行缓存。

接下来你使用编译时编织,所以你不应该使用@EnableAspectJAutoProxy因为已经编织了方面。如果这不起作用你在与你的Eclipse一起设置pom时遇到问题。

尝试让Eclipse和Maven一起工作是(或可能)一项艰巨的任务。关于AspectJ和Maven,请参阅aspectj-maven-plugin not covered by lifecycle in Keplerthis blog也可能会有所帮助。