Can I use Spring's caching features without the annotations? - spring

I'm developing a module I was planning on using Spring's declarative caching to handle. I wrote a number of methods using the cache
#Override
#Cacheable("businessUnitCache")
public BusinessUnit getBusinessUnit(String businessUnitId){
I was planning to provide a classpath beans file and classpath eh-cache configuration to provide the functionality without requiring consuming projects to know the internals of my implementation and which methods need to be cached (many of these methods they'd never access directly).
However, reading the question Using Spring cache annotation in multiple modules and it's answers this is obviously going to cause a problem is any of the consuming projects use Spring cache annotations as well. I was hopeful that Sprint would fail silently if there was no declared cache matching an annotation, but it fails with the error:
java.lang.IllegalArgumentException: Cannot find cache named [businessUnitCache] for CacheableOperation[public
Leading me to the conclusion I can't use the cache annotations (which conflicts with my original conclusion from the question Is it possible to use multiple ehcache.xml (in different projects, same war)?. My testing backs this up.
So: Is it possible to declare the caching separately from the implementation classes, preferably in xml? This would allow me to prepare an additional file with the caching rules, and replace the cache manager name using standard spring property replacement (I'm already doing something similar with the datasource)? Unfortunately the refernece documentation only describes the annotation based configuration.

you can configure the cache using the xml file, see the spring reference manual:
http://static.springsource.org/spring/docs/current/spring-framework-reference/html/cache.html#cache-declarative-xml
<!-- the service we want to make cacheable -->
<bean id="bookService" class="x.y.service.DefaultBookService"/>
<!-- cache definitions -->
<cache:advice id="cacheAdvice" cache-manager="cacheManager">
<cache:caching cache="books">
<cache:cacheable method="findBook" key="#isbn"/>
<cache:cache-evict method="loadBooks" all-entries="true"/>
</cache:caching>
</cache:advice>
<!-- apply the cacheable behaviour to all BookService interfaces -->
<aop:config>
<aop:advisor advice-ref="cacheAdvice" pointcut="execution(* x.y.BookService.*(..))"/>
</aop:config>

Related

How to make Drools KnowledgeAgent be dependant a custom component with Spring configuration?

I have my KnowledgeAgent setup as
<drools:kagent kbase="kbase" id="knowledgeAgent" new-instance="false" >
<drools:resources>
<drools:resource source="classpath:change-set.xml" type="CHANGE_SET" />
</drools:resources>
</drools:kagent>
So it scans the change-set.xml from classpath for resources. And I have another component which will dynamially generate the change-set.xml based on rulefiles found on disk. The spring configuration for this is
<bean id="changesetHandler" class="ChangesetHandler" autowire="byName" lazy-init="true" />
The problem here is that the change-set.xml is generated by my custom component, but I cannot set the Drools KnowledgeAgent component to be dependant on it as it follows it's own schema which does not seem to have depends-on attribute.
Given that a knowledge agent listens for changes, it should reload the knowledge base as soon as your bean generates the change set. Why not load a default empty change set initially and then load the dynamic change set when it has been generated?
Personally I avoid the Drools-Spring components. I find it easier to create a service within my application, which holds my knowledge base. I can then define whatever dependencies I like within that service and ensure that any initialisation has been completed.

Get config setting in custom taglib using Spring "context-property-placeholder"

I'm creating a custom taglib, and would like to use some config options that are loaded via the underlying Spring framework using:
<context:property-placeholder location="classpath:config.properties" />
How would I get access to these variables in my taglib?
Thanks,
James.
The JSP taglibs have nothing in common with the Spring context's lifecycle, they're managed by the servlet container. This can complicate things a bit, for example: inject-dependency-into-a-taglib-class, how-to-write-tag-in-my-spring-project.
Since you're only mentioning the need for contents of the properties file, you could use plain old java.util.ResourceBundle (or, if you need more flexibility, Apache Commons' org.apache.commons.configuration.PropertiesConfiguration).
(One could also argue that requiring access to configuration in your tags indicates a design problem...)

Spring - usage of alias vs names

I am confused on the usage of alias. I do understand what alias is and how it is being used but i don't see how it can be any different than using names on a bean definition.
<bean id="xyx" name="abc,def" .. />
<alias name="xyx" alias="pqr"/>
Why the alias when i can use abc or def?
In my mind bean aliasing can be helpful in large system, where you can not manipulate bean names. You have option to create your own name (alias) specific for your part of the system...
from Spring documentation (3.0.x)
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/htmlsingle/
...it is sometimes desirable to give a single bean multiple names,
otherwise known as bean aliasing...
therefore creating multiple names or/and aliasing are the same thing.
A use case maybe when you want to customize some beans that are already defined somewhere in a modular application (each module is a spring project for example), the bean maybe defined by a third-party framework/API or even your team. In that case you want that only inside your spring project call the customized version without altering other modules (projects), to do that just add the alias in your spring configuration which is indeed a powerful feature:
<alias alias="globalBeanService" name="customizedBeanService" />
Hence, whenever spring find a call to the globalBeanService, it will inject customizedBeanService for you inside your specific module.
Without this feature, you should go through all classes and modify the bean manually!!
An aliased bean will always have higher priority over a non-aliased one, and in case of having different beans with the same alias then the last one declared will have the priority. In other words, the aliased bean will override the non-aliased beans.
This can be particularly useful when creating big projects or when you are building extensions to your project and don't want to touch the original bean definition.
Alias has a specific using scenario which multiple names don't have:
Imagine multiple config xml files in your project, most of which are authored by your colleagues, and you need to add your own config.xml file. Using you'll be able to refer to a bean defined in another config file with a different name that's maybe more meaningful to your config, without having to touch your colleagues' config files.
I recently found another use case where alias easily solved a problem.
When auto configuration is active, Spring Boot provides the bean serverProperties which can be used to access information about the server currently running the web app.
In integration tests (i.e. when #SpringBootTest annotation is present) the same bean is available under the name org.springframework.boot.autoconfigure.web.ServerProperties.
Of course it is possible to use a different profile for integration testing, but that would require manual change of configuration at multiple places. However, simply by adding
<alias name="serverProperties" alias="org.springframework.boot.autoconfigure.web.ServerProperties"/>
the same configuration files can be used for integration tests and in production.
This might be a bug in Spring Boot, however alias easily solve the problem without waiting for a new release. And most certainly I have no possibility to alter the Boot configuration myself.

Implementing a singleton bean in Spring

I am trying to create a cache class for my website using Spring and have added the following code to my applicationContect.xml file:
<bean id="SiteCache" class="Cache.SiteCache">
What I am unsure of is how to initialize this class. Do I even need to initialize it myself or does Spring take care of that when the site loads? If so, how would I accept parameters within the constructor?
I would like the class to be used most of the time, as a quicker way of accessing variables to populate the site, but I need a way of checking if there is an instance in the first place, so that I can load an XML file from source otherwise.
What would be the best way to implement a cache in spring?
Many thanks,
What I am unsure of is how to initialize this class.
By default (providing your definition) Spring will create exactly one instance of bean and use it everywhere where other code requires it.
how would I accept parameters within the constructor?
Check out 4.4.1.1 Constructor-based dependency injection:
<bean id="foo" class="x.y.Foo">
<constructor-arg ref="bar"/>
<constructor-arg value="42"/>
</bean>
and 4.4.2.7 XML shortcut with the c-namespace:
<bean id="foo" class="x.y.Foo" c:_0-ref="bar" c:_1-ref="baz">
What would be the best way to implement a cache in spring?
Using built-in Spring cache abstraction is a good start.
What would be the best way to implement a cache in spring?
In terms of implementing a cache, I would recommend using an existing Cache implementation such as EhCache or similar in conjunction with the Spring cache abstraction.
This makes caching as simple as annotating a method which should access the cache with #Cacheable. Spring will attempt to use the cache before executing the method.
Whilst it might seem simple to write your own cache the hardest part is always the cache invalidation.
It seemed all that was necessary was to load the XML file in the constructor of the cache class. I didn't even need to define a bean in the end, simply accepting it in my GET/POST methods for each controller was enough to keep the cache class a singleton. That way the XML file is only loaded once and saved into a cache object when the site gets built. After that the cache object can be used for easier access.
Thanks for the alternative suggestions though, they seem more effective on more complicated systems and it turned out mine didn't really need all that. I also had a rough idea and only needed a bit of reminding!

Entity Manager per Thread design - how to implement

I want to know how to implement a JPA EntityManager per user thread design. Since EM are light weight objects, it should not be an overhead to create them per user thread. The problem I want to solve is a single JSP page with multiple (parallel) JSON/AJAX calls to back-end services (via controllers).
I am having an Entity Manager (with persistence context EXTENDED), with Open EM In View Filter. It does work nice, but only when there is one user thread (say, a json call) per page, or in other words when I access em in serial fashion.
It does not however solve my purpose when I call my services from multiple threads as em instances are shared and I get weird errors (sometimes shared access to collections, and sometimes closed connection, which are expected I believe).
I am using JPA over Spring 3 and hibernate 3.5. I inject an entity manager (extended) into my services as below:
#PersistenceContext(type = PersistenceContextType.EXTENDED)
protected EntityManager em;
My readonly service methods are annotated as
<tx:method name="get*" read-only="true" propagation="SUPPORTS"/>
All other methods, are annotated as
<tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
I want to avoid an application managed em, and hence did not go for injecting a EntityManagerFactory instead.
Also, If I choose to inject EntityManager into spring controller, I will still have issues when same controller is called in parallel from two threads !
Is there an elegant way to achieve a thread safe access to em. I also want to avoid locking any entity objects, which complicates things further.
Since multiple ajax calls from same page is a very common design in modern web - applications, I believe there must be a simple and declarative way of achieving this (without going back to managing hibernate sessions manually with interceptors etc)
I don't quite understand your problem.
Entity manager per thread is a default behaviour, but you explicitly overrode it with EXTENDED. Do you have any specific reason for configuring it as EXTENDED? If not, all you need is to remove it:
#PersistenceContext
protected EntityManager em;
Spring has a Thread scope, which is disabled by default (See the section 4.5 Bean scopes):
Thread-scoped beans
As of Spring 3.0, a thread scope is available, but
is not registered by default. For more information, see the
documentation for SimpleThreadScope. For instructions on how to
register this or any other custom scope, see Section 4.5.5.2, “Using a
custom scope”.
If you activate the scope, you can just define your entitymanagers as scope=thread
This is the most standard way of working with EM/Sessions, and there are standard tools like OpenSessionInViewFilter (or Interceptor) which creates a session when HTTP Request comes into your servlet container.
Or it can be a Spring Transactional support which creates a session with the help of AOP.
The key point here is to use already existing mechanism or, if you have some extensions, at least copy-paste them.
Spring does this via binding/unbinding the resources to the thread with the help of TransactionSynchronizationManager. You can take a look at Spring sources or here is an example of session-per-conversation pattern which also uses the same means to bind resources to threads.

Resources