Implementing a singleton bean in Spring - 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!

Related

Using RequestScope without ServletModule

I was exploring #RequestScoped and was wondering if there's way to use it without installing ServletModule. I am using Guice 3.0 + Jersey 1.17 and probably don't want to use GuiceContainer & GuiceServletContextListener.
I want object creation(injections) per request depending on some user input in the Jersey request. Is it possible? What can be performance & security considerations of using GuiceContainer if I had to replace my existing ServletContextListener with that of Guice?
If there's a way of using RequestScope as per my needs, can you give me some references for the same?
It is possible to bind a custom Scope implementation to a predefined scoping annotation like #RequestScoped. It does mean that then you cannot use ServletModule, since you can't bind two different implementations to the same scoping annotation.
See the documentation on Custom Scopes for details. You will need to write code to determine what constitutes a "request" for purposes of scoping, and trigger entering and exiting the scope as necessary.
For example, in the normal Guice implementation, ServletScopes.RequestScope uses a ThreadLocal initialized in GuiceFilter to keep track of what the current request is.

Look up a dynamic property at run-time in Spring from PropertySourcesPlaceholderConfigurer?

Not sure of the best approach to this. We've created a jar that could be used by different projects. The other projects relying on this jar need to provide certain properties defined in one of their spring properties files. (Our jar shouldn't care what they name those property files.)
Using #Value("${some.prop}") works great for most properties, however we now have the requirement that the name of the property to look up is dynamic. For example:
int val = getSomeVal();
String propNeeded = foo.getProperty("foo."+val+".dynamic.prop");
Not sure what "foo" should be to get my access. I looked into injecting Environment, however from all my googling it looks like that will not load from an xml property-placeholder definition (even if defined as a bean def for PropertySourcesPlaceholderConfigurer.) You seem to have to use #PropertySource, yet my main config is an XML file so not sure how to get Environment to work. (I can't really go 'old skool' and look up the property file as a class path Resource either since I'm not aware of the name of the file the users defined.)
I don't mind making this particular Service class ApplicationContextAware, but if I did that how could I get access to the underlying PropertySourcesPlaceholderConfigurer ? which I would 'seem?' to need in order to get access to a property dynamically?
The other option is that I force users of the jar to declare a bean by a name that I can look up
<util:properties id="appProps" location="classpath:application.properties" />
And I then inject appProps as Properties and look up from there. I don't like this approach though since it forces the users of the library to name an file by a common id. I would think the best solution is to just get a handle in some way to the underlying PropertySourcesPlaceholderConfigurer in my service class... I'm just not sure how to do it?
Why doesn't Spring simply allow PropertySource to be defined some how via your XML config and then I could just inject Environment?
Thanks for any suggestions how to accomplish what I want.
You could have a ReloadableResourceBundleMessageSource declared to read from the same source as the PropertySourcesPlaceholderConfigurer. This way you could just #Autowire MessageSource (or make your bean implement MessageSourceAware) and use that to retrieve your properties.
Main reason for using ReloadableResourceBundleMessageSource is to retrieve I18N messages, so that would kind of hacky...

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.

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

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>

Resources