Весна: Нужно ли @EnableAspectJAutoProxy с переплетением времени компиляции?
Я просмотрел Интернет и нашел несколько предложений, а также попробовал различные конфигурации, но я совершенно не уверен, работает ли он правильно.
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>
потому что раньше казалось, что мне всегда приходилось делать 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()
занимает 1 мс, потому что все приходит из кеша. - Возвращаемые значения в порядке.
Вопросы:
Почему эти журналы TRACE
Computed cache key x for operation ...
там всегда два раза? Похоже, метод вычисления вызывается дважды?!Конфигурация в порядке? Потому что я не совсем уверен, будет ли это всегда работать так, как ожидалось, особенно потому, что мне пришлось использовать
Project -> Clean
а такжеTomcat -> Clean
иногда. (иначе он просто проигнорировал@Cacheable
аннотации и просто называется метод)
Спасибо!
1 ответ
Прежде всего, ваши текущие настройки никогда не будут работать с @EnableAspectJAutoProxy
, Spring AOP использует прокси для применения аспектов. Ваш @Scheduled
вызывает метод внутри себя и поэтому никогда не пройдет через прокси, и у вас никогда не будет кэширования.
Рядом с этим вы используете ткачество времени компиляции, поэтому вы не должны использовать @EnableAspectJAutoProxy
поскольку аспекты уже сплетены. Если это не работает, у вас есть проблема в настройке вашего pom вместе с Eclipse.
Попытка заставить Eclipse и Maven работать вместе является (или может быть) сложной задачей. Что касается AspectJ и Maven, см. Aspectj-maven-plugin, не охваченный жизненным циклом в Kepler, и этот блог также может быть полезен.