Femtocontainer -- The IoC container built into the JDK
There are many many IoC containers for Java out
there that claim to be the smallest. Well, today I am going to show you one
that cannot be beat.
There have been an endless series of tiny IoC
containers released into the Java community including picocontainer, nanocontainer, spring framework, microspring,
etc, etc. I'm going to take the all time record with this one though. First
some background.JavaBeans were created
as Java's answer to the COM component model. There were properties, events, and
methods. They were serializable so you could store them in little .ser files.
They had design and runtime variations, GUI and non-GUI versions, and all manner
of icons, customizers, etc. They appeared to be designed for integration with
IDEs so you could bring up a palette of components and reuse them in your
applications. During the time between when JavaBeans was released and when EJB
was released a lot of developers, including myself (see Jumping
Beans), created remoteable versions that could be used between VMs and
without GUI representations. This was all quickly stamped out because now there
was a JavaBean solution for inter-VM execution -- but it didn't look much like
JavaBeans. In fact, it was its own component model that only shared the name
and virtually none of the attributes. It felt a lot like annoying Java and
JavaScript naming problem. During this same period of Java history a little
used specification was released, known as the JavaBeans Glasgow specification.
This got virtually no attention but it tried to create a services
and lifecycle system for JavaBeans, but because of the interest in EJB
and the poorly written specification, it has not gotten much attention. This is
an interesting aside, but because there was no IoC framework yet, it would have
been difficult to use anyway.Java
version 1.3 didn't introduce much on this side so we will skip ahead to the
focus of this entry. In Java 1.4 Sun included a much needed encoding and
decoding framework for "JavaBeans". I put JavaBeans in quotations because it is
actually much more powerful than that. It will decode and encode virtually any
Java class you wish because of how flexible it is. Essentially, it lets you
write Java code in an XML file... much like the Spring IoC Framework. Let's
look at a simple configuration using the Spring Framework and then I will show
you the equivalent in the JDK:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- example of list and map and idref and property values -->
<bean id="cityFinder" class="com.tallsoft.springeg.CityScape" singleton="true">
<property name="cityMap">
<map>
<entry key="LDN"><value>London</value></entry>
<entry key="FFT"><value>Frankfurt</value></entry>
</map>
</property>
</bean>
<!-- example of list and depends on for creation ordering-->
<bean id="region" class="com.tallsoft.springeg.RegionInfo" depends-on="cityFinder">
<property name="cityFinder"><idref local="cityFinder"/>
</property> <property name="regions">
<list>
<value>Europe</value>
<value>America</value>
</list>
</property>
</bean>
</beans>
This is a relatively straight-forward
configuration file that specifies two beans, one contains the other and each of
them contains a complicated property. So what is this mysterious IoC framework
that we are going to use in the JDK? It is none other than java.beans.XMLDecoder.
When JavaSoft realized that serializing beans was a nasty business because of
versioning issues they created this class and its brother the XMLEncoder
to take its place. Instead of little "pickled" (nice name Sun) JavaBeans stored
in .ser files you have .xml files with something that is vaguely human readable,
at least as much as that Spring stuff is. So what does the translated system
look like? Here we go:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE javabeans SYSTEM "http://www.javarants.com/schemas/javabeans.dtd">
<java version="1.4.2" class="java.beans.XMLDecoder">
<object id="cityFinder" class="com.sampullara.jbioc.CityScape">
<void property="cityMap">
<object class="java.util.HashMap">
<void method="put">
<string>LDN</string>
<string>London</string>
</void>
<void method="put">
<string>FFT</string>
<string>Frankfurt</string>
</void>
</object>
</void>
</object>
<object id="region" class="com.sampullara.jbioc.RegionInfo">
<void property="cityFinder"><object idref="cityFinder"/></void>
<void property="regions">
<object class="java.util.ArrayList">
<void method="add"><string>Europe</string></void>
<void method="add"><string>America</string></void>
</object>
</void>
</object>
</java>
Interestingly, the format for this file is
slightly more powerful in some ways by being infinitely flexible, but it is
missing some of the abstraction features like templates that the Spring
framework has... at least I think so. I am going to be experimenting with it
some more in coming days since I think I'd rather use something built into the
JDK than add a ton of new frameworks. Here is the code for loading the config
file:
XMLDecoder xmldecoder = new XMLDecoder(getClass().getResourceAsStream("/config.xml"), this);
CityScape cityScape = (CityScape) xmldecoder.readObject();
RegionInfo regionInfo = (RegionInfo) xmldecoder.readObject();
Amazingly, Sun even has some good
documentation on the femtocontainer. I would love to hear from people
what other major features within the spring xml file would be nice to see
implemented using this system rather than Spring or other containers. Next I am
going to be looking at how modern Java users could reuse BeanContext for all
their other container needs....Here is
the sample with a unit test and a build
script.jbioc.jarUpdate:
Here is a schema for the
javabeans XMLDecoder for people who want better validation than the
DTD.
Posted: Wed - February 16, 2005 at 04:00 PM
|