Date: 2004-03-16T19:37:05
Editor: 130.89.169.128 <>
Wiki: JicarillaWiki
Page: http://lsd.student.utwente.nl/jicarilla/IocContainerInternals_2fAdvancedStuff_2fScriptingAndXmlConfigurationFiles
halfway through
Change Log:
------------------------------------------------------------------------------
@@ -4,24 +4,136 @@
''(part of the IocContainerInternals paper)''
-Well, that was a lot of talk about container internals. Let's start talking about how they interface with the application developer. In the majority of cases, this is not just pure java. Some kind of scripting language, or xml configuration files (or an xml-based scripting language), or some custom heuristic or config file, or a mix of those, is used to make the task of assembling components into a container easier.
+Well, that was a lot of talk about container internals. Let's start talking about how they actually interface with the application developer. In the majority of cases, this is not just pure java. Some kind of scripting language, or xml configuration files (or an xml-based scripting language), or some custom heuristic or config file, or a mix of those, is used to make the task of assembling components into a container easier.
== A code example ==
-''TODO''
+We had some pseudocode a while back for constructing an imaginary episode of the simpsons:
{{{
- pure java
+ function assemble()
+ {
+ add( Bart )
+ add( Homer )
+ add( Lisa )
+ add( Maggie )
+ add( Marge )
+ }
+ function wire() { perform-equivalent-of-previous-sample-here() }
+
+ assemble()
+ wire()
+ getMarge().frown()
}}}
+After all the talk about all those container interfaces and patterns, let's just take a look at a plethora of different ways of doing the same thing...
+
+=== Manual java ===
+
+Without any kind of helper objects, facade, builder, or something like that, we're doing a lot of 'wiring' by hand. Maybe something like...
+
{{{
- the same bit in groovy
+ ContainerImpl container = new ContainerImpl();
+ container.initialize();
+ Resolver resolver = container.getResolver();
+ container.addCacher(
+ Bart.class,
+ new SingletonCacher(
+ new BeanFactory(
+ BartImpl.class, resolver
+ )
+ )
+ );
+ container.addCacher(
+ Lisa.class,
+ new PerThreadCacher(
+ new BeanFactory(
+ LisaImpl.class, resolver
+ )
+ )
+ );
+ /* ... add other components here ... */
+ container.start();
+ Marge marge = (Marge)container.getInstance( Marge.class );
+ marge.frown();
}}}
+=== Using a facade ===
+
+Let's consider a builder-like coding pattern that does exactly the same thing...
+
{{{
- the same bit in an xml config file
+ Container container = Builder.newContainer()
+ .add( BartImpl.class, Builder.SINGLETON )
+ .add( LisaImpl.class, Builder.PER_THREAD )
+ /* ... add other components here ... */
+ .create();
+ Marge marge = (Marge)container.getInstance( Marge.class );
+ marge.frown();
}}}
+=== Using a scripting language ===
+
+Let's consider a standalone container that reads a groovy script on startup. The file might contain something like this...
+
+{{{
+ add( BartImpl.class, SINGLETON )
+ add( LisaImpl.class, PER_THREAD )
+ /* ... add other components here ... */
+ get( "Marge" ).frown()
+}}}
+
+=== Using an XML config file ===
+
+That same standalone container, reading an xml file like this one...
+
+{{{
+ <container>
+ <components>
+ <component
+ id="bart"
+ type="Bart"
+ implementation="BartImpl"
+ lifestyle="singleton"/>
+ <component
+ id="lisa"
+ type="Lisa"
+ implementation="LisaImpl"
+ lifestyle="per-thread"/>
+ <!-- ... add other components here ... -->
+ </components>
+ <post-startup>
+ <method-call refid="marge" methodName="frown"/>
+ </post-startup>
+ </container>
+}}}
+
+=== Using attributes ===
+
+Now consider a container that has an ant task associated with it. The ant task will parse your source tree and generate an XML file much like the one above for you. You might use javadoc attributes like this...
+
+{{{
+ /** @component type="Bart" id="bart" lifestyle="singleton" */
+ class BartImpl implements Bart
+ {
+ /* ... */
+ }
+ /** @component type="Lisa" id="lisa" lifestyle="per-thread" */
+ class BartImpl implements Bart
+ {
+ /* ... */
+ }
+ /* ... add other components here ... */
+}}}
+
+and then you might implement the "post startup" bit via a JMX management interface.
+
+=== Glancing over these samples... ===
+
+These approaches seem quite different from each other when you just glance at them. The first one is a complex mess of java method calls but is the most "embeddable" in other java applications (this sample is real easy to run in an IDE, for example). The scripting language example is extremely short but requires learning another language. The XML version has all the benefits of XML but is painful to read. The attribute-based example means you don't need extra source files besides those of your components at all, but does distribute the assembly information across multiple (possibly hundreds) of build files.
+
+At second glance, I hope you can see how these approaches are all reasonably equivalent: all of them accomplish exactly the same, namely the correct execution of the pseudocode example at the start of this page. The current direction in which many container efforts are headed is a very clean seperation between the choice of end-user interaction and their "core" IoC implementation.
+
== Declaration or method calls ==
''TODO''
-------------------------------------------------------
This SF.Net email is sponsored by: IBM Linux Tutorials
Free Linux tutorial presented by Daniel Robbins, President and CEO of
GenToo technologies. Learn everything from fundamentals to system
administration.http://ads.osdn.com/?ad_id=1470&alloc_id=3638&op=click
lmpx.com only provides a reader for public news (NNTP) servers. It is not
affiliated with the servers or forums shown here and is not responsible for
the content of articles, which is written by their respective authors.