Spring ready Prevayler
IoC PrevaylerFactory
Intro
Prevayler is a prevalence (persistence) framework for Java. If is very fast, and quite transparent. As such it works with Plain Old Java Objects (POJOs).
Spring is essentially a technology dedicated to enabling you to build applications using Plain Old Java Objects (POJOs). Spring is an Inversion of Control container.
The concept behind Inversion of Control is often expressed in the Hollywood Principle: "Don't call me, I'll call you."
IoC moves the responsibility for making things happen into the framework, and away from application code. Whereas your code calls a traditional class library, an IoC framework calls your code.
Dependency Injection is a form of IoC that removes explicit dependence on container APIs. Ordinary Java methods are used to inject dependencies such as collaborating objects or configuration values into application object instances.
PrevaylerUtil
In order to create an instance of Prevayler you'll need to use the PrevaylerFactory. This class can be used with Spring's Dependency Injection fine.
If the PrevaylerFactory defaults are not appropriate however configuration in Spring becomes difficult.
PrevaylerFactory fields are not accessible through Java Beans mutators. Instead they can be set through configureXXX() methods.
Writing configuration to deal with these method signatures results in verbose and difficult to maintain setup.
A utility class seemed a better idea in this case: PrevaylerUtil.
The first method I had written allowed creation of normal Prevayler instances.
public static Prevayler create(Serializable newPrevalentSystem, String snapshotDirectory)
{
try
{
PrevaylerFactory factory = new PrevaylerFactory();
factory.configurePrevalenceDirectory(snapshotDirectory);
factory.configurePrevalentSystem(newPrevalentSystem);
factory.configureMonitor(new Log4jMonitor());
factory.configureTransactionFiltering(false); // no royal food tasting
return factory.create();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
The second method allowed creation of a transient Prevayler instances.
public static Prevayler createTransient(Serializable newPrevalentSystem, String snapshotDirectory)
{
try
{
// Use transient prevalence!
PrevaylerFactory factory = new PrevaylerFactory();
factory.configurePrevalenceDirectory(snapshotDirectory);
factory.configurePrevalentSystem(newPrevalentSystem);
factory.configureMonitor(new Log4jMonitor());
factory.configureTransactionFiltering(false); // no royal food tasting
factory.configureTransientMode(true);
return factory.create();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
And the third method allowed the creation of a Skaringa (XML) Prevayler instances.
public static Prevayler createSkaringa(Serializable newPrevalentSystem, String snapshotDirectory)
{
try
{
// Use Skaringa XML serialization
PrevaylerFactory factory = new PrevaylerFactory();
factory.configurePrevalenceDirectory(snapshotDirectory);
factory.configurePrevalentSystem(newPrevalentSystem);
factory.configureSnapshotSerializer(new SkaringaSerializer());
factory.configureJournalSerializer(new SkaringaSerializer());
factory.configureMonitor(new Log4jMonitor());
factory.configureTransactionFiltering(false); // no royal food tasting
return factory.create();
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
Having PrevaylerUtil in place allowed for a cleaner Spring configuration:
<bean id="prevaylerRepo" abstract="true">
<constructor-arg><ref bean="modelimpl"/></constructor-arg>
<constructor-arg type="java.lang.String"><value>data_folder</value></constructor-arg>
</bean>
<bean id="prevayler" class="pa.cka.ge.PrevaylerUtil" factory-method="create"
parent="prevaylerRepo" destroy-method="takeSnapshot" singleton="true" lazy-init="true">
</bean>
<bean id="transientPrevayler" class="pa.cka.ge.PrevaylerUtil" factory-method="createTransient"
parent="prevaylerRepo" singleton="true" lazy-init="true">
</bean>
<bean id="skaringaPrevayler" class="pa.cka.ge.PrevaylerUtil" factory-method="createSkaringa"
parent="prevaylerRepo" destroy-method="takeSnapshot" singleton="true" lazy-init="true">
</bean>
The above snippet also shows how inheritance reduces duplication in a Spring configuration file.