I am trying to create a bean for cacheManager only when a specific cachemanager is not configured.
@Bean
@ConditionalOnProperty(name = "spring.cache.type", matchIfMissing = true)
public CacheManager cacheManager() {
ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager() {
@Override
protected Cache createConcurrentMapCache(final String name) {
return new ConcurrentMapCache(name,
CacheBuilder.newBuilder().expireAfterWrite(30, TimeUnit.SECONDS).build().asMap(), false);
}
};
return cacheManager;
}
This bean is created even when I have the property
spring.cache.type=redis
is configured. Did try different combinations with prefix with no luck. This bean is injected regardless of whether the cache type is specified or not in the application.properties.
2
Answers
Your issue is quite straightforward. You need to understand what is actually happening here.
As you already knows
@ConditionalOnProperty
creates a bean when the propert specify in your annotation is available in youryml
. In your case it isspring.cache.type
.So if you annotate like this
@ConditionalOnProperty(name = "spring.cache.type")
, bean will not created when property not is not available. In other words "condition is false because condition is absent".When you annotate like this
@ConditionalOnProperty(name = "spring.cache.type", matchIfMissing = true)
, bean will created when the property not available because we explicitly mention that bymatchIfMissing = true
. In other words "assume condition is true when property is absent". So obviously condition is true when the property is available.So to fix your issue what you can do something like this, define a
havingValue
that will never put as the value for that property. What happens then, bean will not created even when property is available because value of that property does matches yourhavingValue
.Something like this,
Method 2
You can create custom
Condition
class. Like follows,Then change your
CacheManager
bean as follows.The issue seems to be that the default value of
having
attribute does not work as you expect it to. Reading the reference documentation you will find the following forhaving
:This means, that in your case (because you are not specifying the value), the condition will always match unless you have
spring.cache.type=false
. This is also shown in the reference documentation in the following table (the property value "foo" will actually match the condition ifhavingValue=""
which is actually the default if you do not specify it):Having said all that I would say that your best option would be to create your own
Condition
just like @ray suggested.