I am trying to use Spring Cache (#Cacheable annotation) on method level in the Spring Boot Application, but unlike other google guava cache, I have no idea if Spring Cache will cause a memory leak issue. Because it didn't have a size limitation or refresh policy, where and how long would the data be stored in the application? I assume it'd be memory, but will Spring itself clear it automatically? If not, when there might be millions of requests coming in hitting the application, will that trigger a memory leak issue?
My use case is that I have a heavy method per request, and I would like to only execute that method one time during my current request, after the request is done there is no need to keep the data in Cache, but how would I ensure my Spring Cache would be cleared after each request? I know there is a evict action, however, what if my request errors out before hitting my cache evict method so that it returns 500 directly, that means my last request data would always sit in the cache memory, with more and more requests like that which might cause a memory leak, correct?
In Spring application, Perhaps you can disable the cache by :
spring.cache.type=NONE
The type of cache is by default automatically detected and configured. However you can specify which cache type to use by adding spring.cache.type to your configuration. To disable it set the value to NONE.
As you want to do it for a specific profile add it to that profiles application.properties in this case modify the application-dev.properties and add
spring.cache.type=NONE
This will disable caching.
This will disable caching.
The Spring Framework's caching support and infrastructure, whether consumed through declarative annotation-based caching and demarcation of Spring application components (using either Spring Annotations, e.g. #Cacheable, or with JSR-107, JCache Annotations), or by using Spring's Cache API directly (not common), is simply an "abstraction", hence the Spring Cache Abstraction. There is NO underlying caching provider (implementation of this SPI), by default.
Of course, if you are using Spring Boot (on top of, or to consume the core Spring Framework), and you do not configure an explicit caching provider (see here), such as Redis, then by default, Spring Boot will configure and provide your Spring Boot application with a ConcurrentHashMap caching provider implementation (see here).
When the documentation states:
This is the default if no caching library is present in your application.
It means when no caching library, like Redis (using Spring Data Redis, for instance), is detected on your Spring Boot application classpath.
In general, however, it is a good practice to choose an underlying caching provider implementation, such as Redis, or in your case, Google Guava, which is possible to position as a caching provider implementation in Spring's Cache Abstraction (see here, for example).
Given the Spring Framework's Cache Abstraction is simply a Facade with an caching API/SPI common to multiple caching provider implementations, effectively providing the lowest common denominator for caching functionality (e.g. put, get, evict, invalidate) across caching providers, then to your question, there is no cause of memory leak originating from Spring's "Cache", which really is not even a thing anyway. It is technically the provider implementation's "cache", like Google Guave, Redis, Hazelcast, Apache Geode (VMW GemFire), etc, that would actually be the cause of a memory leak if a leak existed in your application in the first place.
In other words, if there is any memory leak, then it originates with the caching provider.
You should refer to your caching provider's documentation on configuring critical aspects of the cache, such as memory management, that are explicitly stated to be beyond the control of the Spring Framework's Cache Abstraction.
The reason these aspects are beyond the control of the core Spring Framework is simply because the configuration of these low-level cache features (e.g. memory management) is usually very provider specific and varies widely from 1 provider to the next, especially with respect to the capabilities and features.
I hopes this explanation gives you clarity on the position of the Cache Abstraction provided by Spring and its responsibilities.
By adhering to the abstraction then it effectively makes it easier to switch between caching providers if your application requirements, UC or SLAs change.
You can still specify what cache you want. For instance you can use Caffeine which
"... provides an in-memory cache using a Google Guava inspired API"
And you can still configure it for instance for a maximumSize
spring:
cache:
cache-names: instruments, directory
caffeine:
spec: maximumSize=500, expireAfterAccess=30s
To enable it you just have to add the dependency and add the #EnableCaching in a config class (and add #Cacheable of course in your method)
See:
https://github.com/ben-manes/caffeine/
https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#cache-store-configuration-caffeine
https://memorynotfound.com/spring-boot-caffeine-caching-example-configuration/
https://www.baeldung.com/spring-boot-caffeine-cache
I am new to Redis and planning to use it as in memory cache. I am using Lettuce 5.2 client for it.
I have multiple applications which will use redis as in memory cache. My idea is to write library using lettuce like wrapper which can be used by multiple application in order to interact with Redis. That library will manage connection pooling, redis failover cases and command execution etc. so that application writer should not worry about all this and just need to use my library.
Now for this library i am confused on below points :
1) Should i use Spring data redis (it also supports lettuce)? If my objective is to create library then first of all, can i use spring data redis ?
2) What all advantage Spring data redis will give me. I have checked documentation https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/#reference
3) If i don't use Spring data redis then I will just use only lettuce and create client, connention pool etc myself.
I am confused whether i should use spring data redis for creating library or not ?
Can you please help me to clear my confusion ?
You are able to implement custom Repository methods in Spring Data, which has been outlined in other answers on SO such as here: How to add custom method to Spring Data JPA.
So you can easily combine both the out of the box Spring Data Redis functionality with custom Lettuce method code for a Spring Data Repository, I would suggest starting with Spring Data, and if you need to fine tune anything beyond that then write a custom methods with Lettuce.
So long as you can use the same connection pool in Lettuce as Spring Data Redis, you should be able to share that as a resource, the same way you can consider Threads as a resource.
No one can really give you a yes no answer as to what libraries you should or shouldn't use, hopefully you have enough information now to make progress going forward.
If I am supposed to implement Caching in existing Spring application for all web service as well as database call, what would be the best way to implement it? I mean any of the design patterns and caching mechanism that can be used with other required stuffs.
I would appreciate any suggestion provided.
Since you are already using Spring stack, Spring Caching could be a alternative you can consider as it will require very less integration and most of the things come out of the box. You can take a look at simple examples here and here too to get a feel of how it works. However if you want more control on the actual underlying cache implementation and the code to interact with that you can roll out your own easily too, though that will require more code to write at your end.
If you are using springboot you can use the
#EnableCaching and #Cacheable
Since Spring Boot automatically configures a suitable CacheManager to serve as a provider for the relevant cache.
You can find more on https://spring.io/guides/gs/caching/
In addition to Guru's answer.
You can find more info about Spring Boot Caching on https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-caching.html and https://docs.spring.io/spring/docs/4.3.14.RELEASE/spring-framework-reference/htmlsingle/#cache
#EnableCaching is for configuration and #Cacheable is for trigger cache object.
I'm writing an application with Spring MVC which I'd like to be configurable with properties files. I looked into Spring's util namespace and found this:
<util:properties id="MyProperties" location="propertiesPath" />
with this, I can annotate my classes field simply with
#Value("myProperty")
and have the property simply injected. So, it's very simple to read your properties. But when you have to save them, it's not as intuitive.
I've stumbled upon quite a few questions on how to do it properly and I think this represents best what I want to say: Updating a properties file injected by Spring to include a last run timestamp.
My question is: why it's so difficult to save properties in Spring? Am I doing it the wrong way? At this point I am even wondering if saving properties this way is a good practice or if I should use a database.
From Oracle I can read:
The Properties class represents a persistent set of properties. The Properties can be saved to a stream or loaded from a stream.
But Spring seems to make easier only one of them. Please enlighten me.
Thank you.
Spring is largely involved in creating the static, unchanging, structure of your application, and not really involved in transaction processing or business-logic. Often it defines how transactions are to be processed, but it isn't usually involved in the processing itself. We often talk about the separation of the domain model and the architecture -- spring is about architecture.
Writing something out to a store of some kind, say properties to a disk file, is transactional logic (even if you don't need an explicit transaction to do it). It would be one of the end-user features of your system, not part of the architecture -- it would be a feature (even if the end user, in this case, is a sys-admin). Spring has little support for this type of behaviour -- just as it has little support for storing information regarding dynamic changes to the application context.
Using properties like this supposed it read-only. If you need some managing with it, you should better write you custom service with pure java properties handling http://www.mkyong.com/java/java-properties-file-examples/
My application needs some meta data configuration to be loaded at server start up. Meta data are annotations and its do-it-once-forget it-and-use kind. So reading annotations and loading the MetaData objects involves lot of reflection hence I want to do it only once.
Is there any way other than using using Singletons ? I saw #Singleton EJBs which may serve the purpose. But I'm using EJB 3.0 hence that support is not available.
Do you see any other approach (efficient and simple) I can use for this purpose ?
To be more clear :
Using annotations on some classes we are building some configuration objects, that'll be used throughout the application. Hence reading the annotations and building the config objects has to be done only once.
I have found solution for the problem.
I have a #PostConstruct annotated method which reads all the configuration meta data and create the objects. And in the EJB deployment descriptor I configure the initial-number of beans in pool as 1 and also maximum number of beans as 1. Hence this would be a singleton and at the same time would be loaded on server startup.