Created
January 6, 2019 22:03
-
-
Save kubamarchwicki/b9968045ee511f37bd36e299aa5ab03d to your computer and use it in GitHub Desktop.
Enable Spring Cache for abstract classes in Spring
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example.caching; | |
import lombok.Data; | |
import org.slf4j.Logger; | |
import org.slf4j.LoggerFactory; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.boot.CommandLineRunner; | |
import org.springframework.boot.SpringApplication; | |
import org.springframework.boot.autoconfigure.SpringBootApplication; | |
import org.springframework.cache.CacheManager; | |
import org.springframework.cache.annotation.Cacheable; | |
import org.springframework.cache.annotation.CachingConfigurerSupport; | |
import org.springframework.cache.annotation.EnableCaching; | |
import org.springframework.cache.concurrent.ConcurrentMapCacheManager; | |
import org.springframework.cache.interceptor.CacheOperationInvocationContext; | |
import org.springframework.cache.interceptor.CacheResolver; | |
import org.springframework.cache.interceptor.SimpleCacheResolver; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.jdbc.core.JdbcTemplate; | |
import org.springframework.stereotype.Component; | |
import java.util.Arrays; | |
import java.util.Collection; | |
import java.util.List; | |
@SpringBootApplication | |
public class CacheableAbstractClassApp { | |
private static Logger logger = LoggerFactory.getLogger(CacheableAbstractClassApp.class); | |
public static void main(String[] args) { | |
SpringApplication.run(CacheableAbstractClassApp.class, args); | |
} | |
private final Repository<Book> bookRepository; | |
private final Repository<Author> authorsRepository; | |
public CacheableAbstractClassApp(Repository<Book> bookRepository, Repository<Author> authorsRepository) { | |
this.bookRepository = bookRepository; | |
this.authorsRepository = authorsRepository; | |
} | |
@Bean | |
public CommandLineRunner fetchingBooks() { | |
return args -> { | |
logger.info(".... Fetching books"); | |
logger.info("findAll() -->" + bookRepository.findAll()); | |
logger.info("findAll() -->" + bookRepository.findAll()); | |
logger.info("findAll() -->" + bookRepository.findAll()); | |
}; | |
} | |
@Bean | |
public CommandLineRunner fetchingAuthors() { | |
return args -> { | |
logger.info(".... Fetching authors"); | |
logger.info("findAll() -->" + authorsRepository.findAll()); | |
logger.info("findAll() -->" + authorsRepository.findAll()); | |
logger.info("findAll() -->" + authorsRepository.findAll()); | |
}; | |
} | |
} | |
@Configuration | |
@EnableCaching | |
class CachingConfiguration extends CachingConfigurerSupport { | |
final static String CACHE_RESOLVER_NAME = "simpleCacheResolver"; | |
@Bean | |
@Override | |
public CacheManager cacheManager() { | |
return new ConcurrentMapCacheManager(); | |
} | |
@Bean(CACHE_RESOLVER_NAME) | |
public CacheResolver cacheResolver(CacheManager cacheManager) { | |
return new RuntimeCacheResolver(cacheManager); | |
} | |
} | |
class RuntimeCacheResolver | |
extends SimpleCacheResolver { | |
protected RuntimeCacheResolver(CacheManager cacheManager) { | |
super(cacheManager); | |
} | |
@Override | |
protected Collection<String> getCacheNames(CacheOperationInvocationContext<?> context) { | |
return Arrays.asList(context.getTarget().getClass().getSimpleName()); | |
} | |
} | |
interface Dao<T> { | |
List<T> findAll(); | |
} | |
abstract class Repository<T> { | |
protected void simulateSlowService() { | |
try { | |
long time = 3000L; | |
Thread.sleep(time); | |
} catch (InterruptedException e) { | |
throw new IllegalStateException(e); | |
} | |
} | |
public abstract Dao<T> getDao(); | |
@Cacheable(cacheResolver = "simpleCacheResolver") | |
public List<T> findAll() { | |
return getDao().findAll(); | |
} | |
} | |
@Component | |
class SimpleBookRepository extends Repository<Book> { | |
@Autowired | |
JdbcTemplate template; | |
@Override | |
public Dao<Book> getDao() { | |
return () -> { | |
simulateSlowService(); | |
return template.query("SELECT * FROM BOOKS", | |
(rs, rowNum) -> new Book(rs.getString("ISBN"), rs.getString("TITLE"))); | |
}; | |
} | |
} | |
@Component | |
class SimpleAuthorsRepository extends Repository<Author> { | |
@Autowired | |
JdbcTemplate template; | |
@Override | |
public Dao<Author> getDao() { | |
return () -> { | |
simulateSlowService(); | |
return template.query("SELECT * FROM AUTHORS", | |
(rs, rowNum) -> new Author(rs.getString("NAME"))); | |
}; | |
} | |
} | |
@Data | |
class Book { | |
private final String isbn; | |
private final String title; | |
} | |
@Data | |
class Author { | |
private final String name; | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment