Ehcache-Spring-Annotations: How to get cache manager reference? - spring

I am using ehcache-spring-annotations to cache my application data. For this, I have below configuration:
<bean id="ehCacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" >
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
<ehcache:annotation-driven cache-manager="ehCacheManager" />
I want to get the reference of 'net.sf.ehcache.CacheManager' out of configured bean 'ehCacheManager'. So that, I can manually perform put or remove operations directly in cache using 'CacheManager'.
Any way to get reference of 'net.sf.ehcache.CacheManager' out of 'org.springframework.cache.ehcache.EhCacheManagerFactoryBean'?

I used below code to get the cache manager reference in my class:
#Resource
private CacheManager ehCacheManager;

Related

Spring My-batis MapperScannerConfigurer not resolving dat source place holder values

After adding MapperScannerConfigurer bean configuration to the configuration xml to autowire my-batis mappers, getting below datasource bean creation error for placeholder issue. looks like spring unable to resolve the dynamic data source properties from property file. Configuration has PropertySourcesPlaceholderConfigurer defination as well to retrieve the datasource properties(min pool size and max pool size ) from class path file. even though having PropertySourcesPlaceholderConfigurer bean configuration, Integration test failing with below error. Basically it is unable to resolve dynamic properties. Any help is much appreciated..
This is just spring and my-batis based project and I there is no spring boot.
Spring version 5.3
my-batis-spring 2.0.6
java.lang.NumberFormatException: For input string: "${datasource.minpoolsize}"
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="appProperties"
class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>
classpath:configs/application.yaml
</value>
</list>
</property>
</bean>
Instead of configuring MapperScannerConfigurer in the xml, I used #MapperScan on
Spring configuration bean which resolved the issue.

Spring Cloud AWS: optional cache manager

Spring cache configuration allows to fall back to no cache using CompositeCacheManager with fallbackToNoOpCache property set to true. How could this be used with spring-cloud-aws cache manager so that, when a non-existing cache cluster is specified, the composite cache manager falls back to no cache? With an example configuration like this:
<aws-cache:cache-manager>
<aws-cache:cache-cluster name="CacheCluster" />
</aws-cache:cache-manager>
the application just won't start when there's no cluster named CacheCluster configured. When a CompositeCacheManager is configured like this:
<aws-cache:cache-manager id="elasticacheManager">
<aws-cache:cache-cluster name="CacheCluster" />
</aws-cache:cache-manager>
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="elasticacheManager" />
</list>
</property>
<property name="fallbackToNoOpCache" value="true"/>
</bean>
with a non-existing cache CacheCluster, then the application fails to start up complaining: "No bean named 'elasticacheManager' is defined".
Is there a way to create an AWS cache manager programmatically and use something like a FactoryBean for this?
Currently Spring Cloud AWS does not support the configuration of a fallback cache. I will add it to our backlog as a feature request. In the meantime you could use the same workaround I did in the reference application using spring profiles (see ReferenceApplication.java).

spring cache expire using bean property

Is there a way of indicating to expire/evict the cache object based on a property of the POJO cached.
In below code, it caches Foo instance. Foo class has a expiresIn property
class Foo {
Date expiresIn;
}
I want to hint to spring to expire the cache based on the value of expiresIn property of cached element. Is this feasible?
#Cacheable("my-cache-key")
Foo getCachedToken(String userName, String password) throws AuthException
My Cache.xml is below:
<cache:annotation-driven/>
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="mapCacheManager"/>
</list>
</property>
</bean>
<bean id="mapCacheManager" class="org.springframework.cache.concurrent.ConcurrentMapCacheManager">
<property name="cacheNames">
<list>
<value>my-cache-key</value>
</list>
</property>
</bean>
I guess you missed the section name How can I set the TTL/TTI/Eviction policy/XXX feature? from the reference guide.
This is a cache infrastructure abstraction; It's not a cache provider. ConcurrentMapCacheManager is a very simple implementation we provide for testing purposes or for super-simple use cases. If you need an eviction policy, choose a caching library that does support that. Ehcache, Guava or Hazelcast come to mind. All of them have a CacheManager implementation.

context:property-placeholder doesn't resolve references

I have next applicationContext.xml file on the root of classpath:
<context:annotation-config />
<context:property-placeholder location="classpath:props/datasource.properties" />
<bean id="datasource" class="org.apache.commons.dbcp.BasicDataSource"
p:username="${jdbc.username}"
p:password="${jdbc.password}"
p:url="${jdbc.url}"
p:driverClassName="${jdbc.driverclass}"
p:validationQuery="SELECT sysdate FROM dual" />
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="datasource"
p:mapperLocations="classpath:mappers/*-mapper.xml" />
<tx:annotation-driven transaction-manager="txManager" />
<bean id="txManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="datasource" />
<bean id="mappeScannerConfigurere" class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:sqlSessionFactory-ref="sqlSessionFactory"
p:basePackage="com.mypackage" />
props/datasource.properties also exists on the root of classpath with such content:
jdbc.url=myjdbcurl
jdbc.driverclass=myClass
jdbc.username=myUserName
jdbc.password=myPassword
I have a spring managed test where I declare to use previously mentioned applicationContext.xml via next annotations:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:applicationContext.xml"})
When I invoke test method i get next error from spring:
org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverclass}'
As I understand sping didn't resolve reference to jdbc.driverclass.
What have I done wrong?
PS: I'm using spring 3.2.3.RELEASE
**
EDIT
**
Perhaps the problem may be in MapperScannerConfigurer. It is a BeanDefinitionRegistryPostProcessor and as Javadoc says:
Extension to the standard BeanFactoryPostProcessor SPI,
allowing for the registration of further bean definitions
before regular BeanFactoryPostProcessor detection kicks in
So MapperScannerConfigurer instantiates datasource object via sqlSessionFactory with BeanFacoryPostProcessor(which is responsible for <context:property-placeholder/>) have not been utilized.
So my question transforms to how to reorder BeanFacoryPostProcessor from <context:property-placeholder/> and BeanDefinitionRegistryPostProcessor(MapperScannerConfigurer)?
Resolved
After a couple hours of investigation I found the solution:
As I said earlier MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor which fires before BeanFactoryPostProcessor which is responsible for <context:property-placeholder/>. So, during the creation of MapperScannerConfigurer references to external properties will not be resolved. In this case we have to defer the creation of datasource to the time after BeanFactoryPostProcessorhave been applied. We can do that in several ways:
remove p:sqlSessionFactory-ref="sqlSessionFactory" from MapperScannerConfigurer. In this case datasource object will not be created before MapperScannerConfigurer, but after BeanFactoryPostProcessor which is responsible for <context:property-placeholder/>. If you have more than one sqlSessionFactory in applicationContext, than can be some troubles
In versions of mybatis-spring module higher than 1.0.2 there is a possibility to set sqlSessionFactoryBeanName instead of sqlSessionFactory. It helps to resolve PropertyPlaceHolder issue with BeanFactoryPostProcessor. It is a recommended way to solve this issue described in mybatis-spring doc
I was having the same issue and came across this post but I was unable to resolve it the same way maks did. What ended up working for me was to set the ignoreUnresolvablePlaceholders property value to true.
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:database.properties</value>
</property>
<property name="ignoreUnresolvablePlaceholders" value="true"/>
</bean>
I am using Spring 3.2.3.RELEASE as well. I realize this post is over 4 months old but I figured someone might find it useful.
Short form: What is the proper way to load an implementation of: BeanDefinitionRegistryPostProcessor?
Expanded form: Is there a way to load BeanDefinitionRegistryPostProcessor before any beans have been created. If you look at the javadoc:
Extension to the standard {#link BeanFactoryPostProcessor} SPI, allowing for
the registration of further bean definitions before regular
BeanFactoryPostProcessor detection kicks in.
So it's meant to be loaded when bean definitions have been created but before any beans have been created. If we just create it as a regular bean in the application xml then it defeats the purpose of having this bean in the first place.

Configuring Datasource in Spring 3.0

Hello guys I have configured a connection pool and JNDI resource in glassfish 2.1. I can get the Datasource via lookup method in my projects and everything works good. However I decided to try Spring framework and to use my existing connection pool.
In the Spring context file I have the following:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/name" />
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
<constructor-arg ref="dataSource"/>
</bean>
<bean id="dao" class="com.mycompany.mavenproject3.Dao">
<property name="simpleJdbcTemplate" ref="jdbcTemplate"/>
</bean>
When I deploy the project I get:
java.lang.IllegalArgumentException: 'dataSource' or 'jdbcTemplate' is required]
Is there anything else I have to configure in that file or in any other file in order to get the Datasource?
Presumably, com.mycompany.mavenproject3.Dao extends JdbcDaoSupport, but you're setting a property named simpleJdbcTemplate on it, leading me to believe that you've defined your own property to hold the template since that doesn't exist on Spring's implementation. It's therefore complaining at you because you're required to set either the dataSource property or the jdbcTemplate property of the JdbcDaoSupport object before using it, exactly like it's telling you. Change <property name="simpleJdbcTemplate"... to <property name="jdbcTemplate"....
If your DAO doesn't extend JdbcDaoSupport, then find what does and remove it or set its properties appropriately.
You can also call your datasource directly in your dao bean, don't need to do an another bean for jdbcTemplate. So your context file become something like this:
<jee:jndi-lookup id="dataSource" jndi-name="jdbc/name" />
<bean id="dao" class="com.mycompany.mavenproject3.Dao">
<property name="dataSource" ref="dataSource"/>
</bean>
After you just have to extends JdbcDaoSupport spring class (in which contain the getter and setter of datasource) on your Dao class.

Resources