Use NCache as Spring Data Cache

NCache, as an in-memory, extremely fast, and scalable distributed cache, provides integration with Spring to boost the application performance by reducing expensive data trips.

Spring is a lightweight dependency injection and aspect-oriented development container and framework for Java. It lets you simplify your application development and plug in reusable pieces in your application like NCache.

 

Why Integrate your Spring Application with NCache?

Spring itself reduces the overall complexity of Java development by providing cohesion and loose coupling, but it creates high traffic in these applications. These high-traffic Spring applications face a significant scalability problem. Therefore, an in-memory distributed cache that meets their scalability requirements is critical.

Although these applications can scale up by adding more servers to their server farm - unfortunately, databases cannot scale to handle such high loads. For these scenarios, a distributed cache is the best at handling the database scalability problem.

Therefore, the best option is NCache. It is a speedy, in-memory, key-value store distributed cache, which has implemented a Spring caching module, making your Spring applications scalable and distributed. It offloads your database by reducing the expensive database trips that cause scalability problems and provides faster performance.

 

How to Configure Spring Application to Use NCache

NCache provides Spring caching support in the following two ways:

  • Through the Spring Caching Provider, NCache acts as a cache manager for your Spring application.
  • Through the JCache Caching Provider, NCache uses the supported feature of JCache.
 

Adding Dependencies

For configuring your Spring application with, first, you must add all the required Maven dependencies that Spring and NCache provide.

<dependency>
    <groupId>com.alachisoft.ncache</groupId>
    <artifactId>ncache-spring</artifactId>
    <version>x.x.x</version>
</dependency>
 

Configure Spring Application through Spring Caching Provider

After adding these dependencies, define beans in your Spring Application - through the Java-based or XML-based Bean Definition.

Java-based Bean Definition:
For defining beans using Java-based definition, you need to add the @Bean annotation in the CachingConfiguration class, where the setConfigFile method will specify the path to your ncache-spring.xml file. For detailed information, refer to Java-based Bean Definition.

@Configuration
class CachingConfiguration {
    @Bean
    public CacheManager cacheManager() {
        String resource = Path.of(System.getenv("NCHOME"), "config/ncache-spring.xml").toString();

        SpringConfigurationManager springConfigurationManager = new SpringConfigurationManager();
        springConfigurationManager.setConfigFile(resource);

        NCacheCacheManager cacheManager = new NCacheCacheManager();
        cacheManager.setSpringConfigurationManager(springConfigurationManager);

        return cacheManager;
    }
}

XML-based Bean Definition:
For defining beans using XML-based definition, you need to add an XML file that enables caching and specifies NCache as a cache manager. You have to define Bean tags for both the cacheManager and NCacheConfigurationManager. Additionally, you must specify the following properties for cacheManager.

  • springConfigurationManager: Reference to NCache configuration manager bean.
  • logFilePath: Fully qualified path for cache manager logs.
<bean id="cacheManager" class="com.alachisoft.integrations.spring.NCacheCacheManager">
	<property name="springConfigurationManager" ref="NCacheConfigurationManager"/>
	<property name="logFilePath" value=" C:\Program Files\NCache\log-files\CustomerDBSpringLogs"/>
</bean>
<bean id="NCacheConfigurationManager" class="com.alachisoft.integrations.spring.configuration.SpringConfigurationManager">
        <property name="configFile" value="ncache-spring.xml">
</bean>

For details, go to XML-based Bean Definition.

Further, you must configure your caches in the ncache-spring.xml file for the NCache Management Centre. Each cache needs its own definition with its own set of properties in this file. For example:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<application-config default-cache-name="books">
  <caches>
    <cache name="books" ncacheid-instance="democache" priority="normal" expiration-type="absolute" expiration-period="300"/>
  </caches>
</application-config>
 

Configure Spring Applications through JCache Caching Provider

Spring also supports JCache-compliant caching providers where you can use JCache in your Spring application with NCache. First, add Maven dependencies for Spring, NCache, and JCache. After adding dependencies, configure caches:

  • Add spring.cache.cache-names tag in the application.properties file. The cache name should be the same as configured in the NCache Management Centre.
  • Configure your cache through the JCacheManagerCustomizer class that initializes the cache at runtime with the desired configuration.

For more information, you can see our JCache Spring Docs.

 

Identifying Methods Needed to be Cached

Once you enable caching through both the configurations defined above, the next step is to bind these caching behaviors to their respective methods to use NCache as a Caching Provider for Spring.

You can bind caching behaviors to their methods in two ways. One is through Caching Annotations.

// BookController.java
@RestController
@RequestMapping("/books")
public class BookController {
    @Autowired
    // Get a Spring Service to save objects in the DB. This also caches them with 5min absolute (TTL) expiration.
    BookService service = context.getBean(BookService.class);
    service.save(new Book(18001, "The Second Machine Age", "Erik Brynjolfsson, Andrew McAfee", new Date(2014, 0, 20)));

    // Print all saved books details
    printBooks(service.listAll());

    // Use Spring Service to get a book from the DB. It actually comes from the cache
    Book foundBook = service.findBookByIsbn(18001);
    printBookDetails(foundBook);

    foundBook.setAuthor("New Author");
    Book UpdatedBook = service.update(foundBook);

    printBookDetails(UpdatedBook);
    context.close();
    System.exit(0);
    }

// BookService.java
@Service
class BookService {
    @Autowired
    private BookRepository repo;

    public List<Book> listAll() {
        return repo.findAll();
    }

    @CachePut(value = "demoCache", key = "#book.getISBN()")
    public Book save(Book book) { return repo.save(book); }

    @CachePut(value = "demoCache", key = "#book.getISBN()")
    public Book update(Book book) { return repo.save(book); }

    @Cacheable(value = "demoCache", key = "#id")
    public Book get(int id) {
        return repo.findById(id);
    }

    @Cacheable(value = "demoCache", key = "#isbn")
    public Book findBookByIsbn(long isbn) {
        return repo.findBookByIsbn(isbn);
    }

    @CacheEvict(value = "demoCache", allEntries = true)
    public void delete(int id) {
        repo.deleteById(id);
    }
}

If you do not use annotations, then Declarative XML-based Caching can be used where you can specify the target method and caching directives externally.

<!-- the service we want to make cacheable -->
<bean id="bookService" class="x.y.service.BookService"/>
<!-- cache definitions -->
<cache:advice id="booksCacheAdvice" cache-manager="cacheManager">
    <cache:caching cache="demoCache">
        <cache:cacheable method="getBookNameByIsbn" key="#isbn"/>
        <cache:cache-evict method="loadBooks" all-entries="true"/>
    </cache:caching>
</cache:advice>

What to Do Next?

Signup for monthly email newsletter to get latest updates.

© Copyright Alachisoft 2002 - . All rights reserved. NCache is a registered trademark of Diyatech Corp.