Sponsored Link •
|
Summary
Okay this came from a little idea I had last night for Neon, and from a bit of playing around with those ideas - dependency injection from Jini configuration files.
Advertisement
|
Dependency injection, for those few who haven't heard of it, is closely linked to moving the responsibilty for creation and retrieval of dependent objects, outside of your classes and modelling that responsibility within a framework environment, essentially the opposite of Service Locator.
DI is also closely linked (for better or worse) with XML configurations. One of the things that I've been considering in Neon, is whether Dependency Injection can work across an environment where mobile code is employed and objects can move around a network. As part of this, I've not really wanted to increase the number of things you have to deal with in Neon - you have to build an agent, and you can supply a Jini configuration file, but you can also supply a constraints file (a kind of simple set of QoS requirements) which can also be decribed in a Jini configuration file......so the next step when looking at Neon, was "Could I model DI in a Jini configuration?". This is a blog of my experiences so far.
Okay, a bit of background on Jini configuration files. Basically Jini allows you to specify deployment time considerations in a separate file, that can be read by your service at runtime, so for instance you may want to export your service in development with a simple non-secure exporter, however when you move into production, you can specify secure SSL exporters with JAAS, etc. without having to mess with your code. Here there is a similarity in what happens with DI.
However, DI also does the injection (hence the name) of field values (through either setter or constructor injection) from this configuration file, so that when you want to know the name of, say, the JDBC driver you will use, you don;t have to retrieve it yourself. With Jini you have to obtain this from a Configuration instance, using Configuration#getEntry(component,entry,typeclass). Jini Configuration files have a java like syntax and perform construction of objects when you ask for the entry. An example is given below
import net.jini.lookup.entry.*; import net.jini.core.entry.*; //Component Name org.sample.myproduct{ //entryName = entryValue simpleString = "abc"; testString=simpleString; logLevel="FINEST"; groups=new String[]{"production"}; initialLookupAttributes = new Entry[] {new Name("TestingConfigScan")}; }
So a Jini configuration provider will take care of creating your objects, and you can call static methods in a configuration file, but not methods on an instance so for instance I could call String.valueOf(...)
, but not simpleString.substring(...)
Now here's where a bit of magic comes in (but only a little), to do some form of Dependency Injection. If we assume certain things about the component name, and look for certain type of setter methods, we could do the following.
import net.jini.lookup.entry.*; import net.jini.core.entry.*; import net.jini.jeri.*; import net.jini.jeri.tcp.*; org.jini.projects.neon.di.Simple{ // <= This refers to a class name SimpleString = "abc"; testString=SimpleString; logLevel="FINEST"; groups=new String[]{"production"}; initialLookupAttributes = new Entry[] {new Name("TestingConfigScan")}; myExporter = new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory()); theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1"); }And a class definition (I've removed getters for brevity)
class Simple { private String testString; private Entry[] initialLookupAttributes; private Exporter myExporter; private Dependent theDependent; public void setTheDependent(Dependent theDependent) { this.theDependent = theDependent; } public void setTestString(String testString) { this.testString = testString; } public void setInitialLookupAttributes(Entry[] initialLookupAttributes) { this.initialLookupAttributes = initialLookupAttributes; } public void setMyExporter(Exporter myExporter) { this.myExporter = myExporter; } }You'll note that the configuration file contains this line:
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1");
org.jini.projects.neon.di.Dependent$Test1{ myString="Hello"; } org.jini.projects.neon.di.Dependent$Test2{ myString="There"; }And create another class:
class Dependent { private String myString; public String getMyString() { return myString; } public void setMyString(String myString) { this.myString = myString; } public String toString() { return myString; } }I can then change the reference in the org.jini.projects.neon.di.Simple component from
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test1");
theDependent=new DIReference("org.jini.projects.neon.di.Dependent$Test2");
Have an opinion? Be the first to post a comment about this weblog entry.
If you'd like to be notified whenever Calum Shaw-Mackay adds a new entry to his weblog, subscribe to his RSS feed.
Calum Shaw-Mackay is an architect on Java and Jini systems, working in the UK. His interests lie in distributed computing, adaptability, and abstraction. Calum has been using Jini for longer than he would care to mention. His main area for taking the blame (some people would call it 'expertise') is systems integration and distributed frameworks, and is an advocate of using Jini's unique strengths to build adaptable enterprise systems. His opinions are his own. He's tried to get other people to take his opinions off him, but they just won't. |
Sponsored Links
|