标签: spring-cache

Spring的AspectJ模式缓存与AspectJ模式事务

我的问题与Spring的AspectJ模式有关,特别是如何启用它:

  1. 交易管理
  2. 高速缓存

1)我注意到为了启用AspectJ模式进行事务管理,我只需要执行以下操作:

@Configuration
@EnableTransactionManagement(mode = AdviceMode.ASPECTJ)
Run Code Online (Sandbox Code Playgroud)

2)为了使用AspectJ模式进行缓存,似乎必须:

- 将以下jar放入Tomcat的lib目录: - org.springframework:spring-instrument-tomcat 在Tomcat的server.xml中添加以下行:

<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"/>
Run Code Online (Sandbox Code Playgroud)

- 添加以下配置:

@Configuration
@EnableLoadTimeWeaving(aspectjWeaving = AspectJWeaving.ENABLED)
public class LoadTimeWeavingConfiguration implements LoadTimeWeavingConfigurer {
    @Override
    public LoadTimeWeaver getLoadTimeWeaver() {
        return new ReflectiveLoadTimeWeaver();
    }
}
Run Code Online (Sandbox Code Playgroud)

- 最终能够使用AspectJ模式如下:

@Configuration
@EnableCaching(mode = AdviceMode.ASPECTJ)
Run Code Online (Sandbox Code Playgroud)

以上是对的吗?如果是这样,为什么AspectJ模式缓存与AspectJ模式事务支持不同?

aspectj spring-aop spring-data-jpa spring-cache

6
推荐指数
1
解决办法
1141
查看次数

在@PostConstruct期间使用@Cacheable的Spring缓存不起作用

与spring框架中的提交有关https://github.com/spring-projects/spring-framework/commit/5aefcc802ef05abc51bbfbeb4a78b3032ff9eee3

初始化设置为从afterPropertiesSet()afterSingletonsInstantiated()的后续阶段

简而言之:这可以防止在@PostConstruct用例中使用缓存时缓存工作.

更长的版本:这可以防止您使用的用例

  1. 在methodB上使用@Cacheable创建serviceB

  2. 使用@PostConstruct调用serviceB.methodB创建serviceA

    @Component 
    public class ServiceA{
    
    @Autowired
    private ServiceB serviceB;
    
    @PostConstruct
    public void init() {
        List<String> list = serviceB.loadSomething();
    }
    
    Run Code Online (Sandbox Code Playgroud)

这导致org.springframework.cache.interceptor.CacheAspectSupport现在不进行初始化,因此不会缓存结果.

protected Object execute(CacheOperationInvoker invoker, Object target, Method method, Object[] args) {
   // check whether aspect is enabled
   // to cope with cases where the AJ is pulled in automatically
   if (this.initialized) {
//>>>>>>>>>>>> NOT Being called
      Class<?> targetClass = getTargetClass(target);
      Collection<CacheOperation> operations = getCacheOperationSource().getCacheOperations(method, targetClass);
      if (!CollectionUtils.isEmpty(operations)) { …
Run Code Online (Sandbox Code Playgroud)

java postconstruct spring-cache

6
推荐指数
2
解决办法
3247
查看次数

带有自定义cacheResolver的spring缓存

我想要动态缓存名称,spring 4.1 允许这样做

从 Spring 4.1 开始,缓存注释的 value 属性不再是强制性的,因为无论注释的内容如何,​​CacheResolver 都可以提供此特定信息。

请注意我如何偏执地设置cacheResolver所有可能的级别:

@Cacheable(cacheResolver = "defaultCacheResolver")
@CacheConfig(cacheResolver = "defaultCacheResolver")
public interface GatewayRepository extends CrudRepository<Gateway, Integer> {
    @Cacheable(cacheResolver = "defaultCacheResolver")
    Gateway findByBulkId(int bulkId);
}
Run Code Online (Sandbox Code Playgroud)

Spring 4.1.5 仍然无法验证配置并出现错误:Caused by: java.lang.IllegalStateException: No cache names could be detected on 'public abstract skunkworks.data.Gateway skunkworks.repos.GatewayRepository.findByBulkId(int)'. Make sure to set the value parameter on the annotation or declare a @CacheConfig at the class-level with the default cache name(s) to use. at org.springframework.cache.annotation.SpringCacheAnnotationParser.validateCacheOperation(SpringCacheAnnotationParser.java:240)

spring spring-data spring-cache

6
推荐指数
1
解决办法
2万
查看次数

为什么这个stream&lambda表达式不能与SpEL声明一起使用?

我正在尝试在Spring @Cache注释中使用Java 8流和lambda表达式.

我正在尝试使用以下内容:

@CacheEvict(value = "tags", allEntries = true, 
condition = "#entity.getTags().stream().anyMatch(tag -> tag.getId() == null)")
Run Code Online (Sandbox Code Playgroud)

失败的是:

SEVERE: The RuntimeException could not be mapped to a response, re-throwing to the HTTP container
org.springframework.expression.spel.SpelParseException: 
EL1042E:(pos 40): Problem parsing right operand
Run Code Online (Sandbox Code Playgroud)

但是,如果我将流移动到实体上的方法中,我能够使它工作.然后注释如下工作,没有错误:

@CacheEvict(value = "tags", beforeInvocation=true, allEntries = true, 
condition = "#entity.containsNewTag()")
Run Code Online (Sandbox Code Playgroud)

我宁愿不需要'containtsNewTag()'方法,如果可能的话,直接在SpEL表达式中使用流.可以这样做吗?

spring spring-el spring-cache

6
推荐指数
2
解决办法
2880
查看次数

在采用带有数组或集合参数的方法上使用Spring Cache存在哪些策略?

我想使用Spring的Cache抽象将方法注释为@Cacheable。但是,某些方法被设计为采用参数的数组或集合并返回一个集合。例如,考虑使用以下方法查找实体:

public Collection<Entity> getEntities(Collection<Long> ids)
Run Code Online (Sandbox Code Playgroud)

从语义上讲,我需要Entity单独缓存对象(由id键),而不是基于整个ID的集合。类似于这个问题在问什么。

简单的Spring Memcached通过其支持了我想要的ReadThroughMultiCache,但是我想使用Spring的抽象来支持轻松更改缓存存储实现(Guava,Coherence,Hazelcast等),而不仅仅是memcached。

有哪些策略可以使用Spring Cache缓存这种方法?

spring caching spring-cache

6
推荐指数
1
解决办法
5142
查看次数

使用Spring缓存处理Java 8可选

考虑一个可以插入和检索对象并使用Spring缓存抽象的服务类,如何以返回Optional的方式注释方法?

class MyServiceImpl implements MyService {

    private static final String CACHE_NAME = "itemCache";      

    @Override
    @Cacheable(CACHE_NAME)
    public Optional<Item> findById(Long id) {
        // access the repository to retrieve the item
    }

    @Override
    @CachePut(cacheNames = CACHE_NAME, key = "#item.id")
    public Item insertItem(Item item) {
        ...
    }

}
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,ClassCastException抛出了a ,因为insertItemItem实例放入缓存中,并findById期望Optional可能包含Item实例.

java spring spring-cache

6
推荐指数
1
解决办法
3045
查看次数

Spring Cache-创建自定义CacheManager

我正在使用Spring Boot和EhCache开发日历应用程序。我正在尝试缓存以下方法:

@Override
@Cacheable(value = "concerts")
public List<Event> getEvents(String eventsForUser, Date startDate, Date endDate) throws Exception {
    return fetchEventsFromTheServer(eventsForUser, startDate, endDate);
}
Run Code Online (Sandbox Code Playgroud)

挑战是我想操纵返回的缓存结果。例如,检查是否存在给定日期但另一个用户的缓存,然后取而代之(只要两个用户都符合特定条件)。

因此,在返回结果之前,我想:

  • 获取所有缓存条目的列表
  • 遍历所有这些,并检查所需的日期/用户
  • 如果找到合适的-退还
  • 如果未找到-缓存不可用,请运行该方法。

我认为最好的办法是创建一个自定义缓存管理器,该缓存管理器将对缓存的Concert执行所有操作,并对所有其他方法使用默认的自动配置的缓存,但是我无法让我的自定义管理器正常工作并且没有发现任何好处如何实现自定义CacheManager的示例。

这是我所拥有的:

Application.java:

@SpringBootApplication
@ComponentScan
@EnableCaching
@EnableScheduling
public class SpringBootWebApplication extends SpringBootServletInitializer {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootWebApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(applicationClass);
    }

    private static Class<SpringBootWebApplication> applicationClass = SpringBootWebApplication.class;


    @Bean(name = "eventsCacheManager")
    public EventsCacheManager eventsCacheManager() {

        return new EventsCacheManager();
    }

    @Primary
    @Bean(name = "cacheManager") …
Run Code Online (Sandbox Code Playgroud)

java ehcache spring-boot spring-cache

6
推荐指数
1
解决办法
1万
查看次数

使用@EnableCaching的Spring Boot默认缓存管理器

我在SpringBootApplication中实现了缓存,如下所示

@SpringBootApplication
@EnableCaching
public class SampleApplication extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(SampleApplication.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(SampleApplication.class, args);
    }
Run Code Online (Sandbox Code Playgroud)

这绝对是正常的.

但是要实现缓存,应该定义一个必需的CacheManager/Cacheprovider.没有定义任何cacheManager也我的应用程序工作正常.

是否有Spring定义的默认缓存管理器?Spring文档说Spring Boot自动配置一个合适的CacheManager.

那么如果我们不定义CacheManager会使用什么呢?

caching spring-boot spring-cache

6
推荐指数
2
解决办法
1万
查看次数

如何检测@Cacheable方法输出是否来自缓存?

有一个用@Cacheable注释的方法返回一个对象:

@Service
public class UserService {

  @Cacheable("userData")
  public UserData getUserData(String userName) {
    UserData userData = new UserData();
    userData.setGotFromCache(false);
    return userData;
  }

}
Run Code Online (Sandbox Code Playgroud)

和 UserData 对象:

@Getter
@Setter
public class UserData {
  private boolean gotFromCache;
}
Run Code Online (Sandbox Code Playgroud)

如何检测@Cacheable注解的方法是否被调用或者其输出是否来自缓存?

解决方法是注入 CacheManager 并手动检测它:

Cache cache = this.cacheManager.getCache("userData");
UserData userData = null;
String userName = "some user name";
if (cache != null) {
  Object key = SimpleKeyGenerator.generateKey(userName);
  userData = cache.get(key, UserData.class);
  if (userData != null) {
    userData.setGotFromCache(true);
  } else {
    userData = userService.getUserData(userName);
    cache.put(key, userData); …
Run Code Online (Sandbox Code Playgroud)

spring ehcache spring-annotations spring-cache

6
推荐指数
1
解决办法
2028
查看次数

Spring Cache Caffeine 批量检索

是否可以将咖啡因CacheLoader::loadAll@Cacheable带有集合参数的带注释方法一起使用,例如

@Cacheable(cacheNames = "exampleCache", cacheManager="exampleCacheManager", keyGenerator = "complexKeyGenerator")
   List<String> getItems(List<String> keys, String commonForEveryKey) {
      return ...
}

@Component
class ComplexKeyGenerator implements KeyGenerator {

      @Override
      public Object generate(Object target, Method method, Object... params) {
         return ((List<String>)params[0]).stream()
                     .map(item -> new ComplexKey(item, (String) params[1]))
                     .collect(Collectors.toList());
      }
}

@Data
   @AllArgsConstructor
   class ComplexKey {
      String key;
      String commonGuy;
}

class CustomCacheLoader implements CacheLoader<ComplexKey, String> {

      @Override
      public @Nullable String load(@NonNull ComplexKey key) throws Exception {
         return loadAll(List.of(key)).get(key);
      }

      @Override
      public @NonNull …
Run Code Online (Sandbox Code Playgroud)

spring spring-boot spring-cache caffeine-cache

6
推荐指数
1
解决办法
1270
查看次数