javafx dependency injection with fxcontainer
Post on 18-Nov-2014
3.462 Views
Preview:
DESCRIPTION
TRANSCRIPT
JavaFX Dependency
Injection with
FxContainer
Presented by
Srikanth Shenoy
ObjectSource
Learn FxContainer in 10 minutes
Introduction
Who am I?
A hands-on architect
Experienced and very knowledgeable in Java and
Java EE
Authored a book on Struts
Several articles on Java EE for leading journals
Director of Enterprise Java Practice at
ObjectSource
Creator of FxObjects and FxContainer framework
Introduction
What is FxContainer? (Currently 1.0)
Open source IoC container written in JavaFX.
Meant specifically for Dependency Injection in
JavaFX applications
Very much Spring-like
Small footprint (< 75K)
Sequence, Collection Support
Mix Java and JavaFX wiring
Learn FxContainer in 20 slides! (10 minutes)
IoC Container Landscape
Spring
Supports XML and Annotations based DI
Supports Constructor & Setter Injection
Guice
Supports Annotations and API based DI
Supports Constructor & Setter Injection
PicoContainer and many more..
Why another IoC Container?
Problems with existing IoC Containers (in the
context of JavaFX)
JavaFX does not support annotations
Hence Guice leaves only programmatic DI option
Xml DI with Spring works, but minimal jars > 1 MB
Constructor Injection not supported in JavaFX
Setter Injection is unnatural for JavaFX style
JavaFX variables are written as public or public-init
Writing setXYZ() method for variables feels artificial
Nobody supports Sequence (the first class
JavaFX collection citizen)
Setter Injection
var finder = MovieFinder {
movieDao: MovieDao { }
}
Dependency Injection with any other IoC
container needs a setter like this (Not Good)public class MovieFinder {
public-init movieDao:MovieDao;
public function setMovieDao(dao:MovieDao) {
this.movieDao = dao;
}
}
Side effects of Setter Injection
Init and Post-Init code that depends on
public-init variables will not work
Classic Example – CustomNode.create()
Called automatically in every UI
Called immediately after init and post init
No time to call setter methods
If create() depends on objects injected by setter
injection, then it will fail !!
A Different Kind of Injection
Constructor Injection is DURING memory
allocation
Setter Injection is AFTER memory allocation
and object initialization
JavaFX needs something in between the two
We call it Init injection
A DI based on Init Injection does not exist
So we created it
FxContainer is the ONLY IoC container that
provides Init Injection for JavaFX
FxContainer Core Concept
Based on JavaFX Reflection and Init InjectionFXLocal.Context ctx = FXLocal.getContext();
//get the class
FXClassType clzType = ctx.findClass("org.fxobjects.MovieFinder");
FXObjectValue objValue = clzType.allocate(); //allocate memory
//get the variable-type
FXVarMember varMember = clzType.getVariable("movieDao");
//create the variable-value
FXValue varValue = ctx.mirrorOf(Some String or object);
objValue.initialize(); //Finally initialize the object
//initialize the variable. Basis for FxContainer Init Injection
objValue.initVar(varMember, varValue);
FxContainer Overview
Uses Setter Injection for Java objects
Uses Init Injection for JavaFX objects
Can mix both Java and JavaFX objects
Java objects can hold references to JavaFX
objects via interfaces
Very Spring Like in configuration
Powerful, Lightweight and Easy to use
FxContainer: Simple
Dependency Injection
<fxcontainer>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="someVar" value="Some random value"/>
<property name="javaHelper" ref="javaHelperObj"/>
<property name="jfxHelper" ref="jfxHelperVarObj"/>
</fxobject>
<fxobject name="movieLister"
class="org.fxobjects.samples.fxcontainer.MovieLister">
<property name="finder" ref="movieFinder"/>
</fxobject>
</fxcontainer>
FxContainer: Import XML
Good for organizing large XML into smaller
logical chunks<fxcontainer>
<import resource="/org/fxobjects/samples/abc.xml"/>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="someVar" value="Some random value"/>
<property name="javaHelper" ref="javaHelperObj"/>
<property name="jfxHelper" ref="jfxHelperVarObj"/>
</fxobject>
</fxcontainer>
FxContainer: Import Properties
Good for Spring style ${ } substitutions <fxcontainer>
<import resource="/org/fxobjects/samples/abc.properties"/>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="someVar" value=“${svr1Name} is ${svr1Status}"/>
<property name="javaHelper" ref=“${helperObj}"/>
<property name="jfxHelper" ref="jfxHelperVarObj"/>
</fxobject>
</fxcontainer>
value and ref can be substituted
FxContainer: Wired Object
Attributes
Wired Objects in FxContainer have the following defaults
(can be overridden)
Every wired object is singleton
Every wired object is lazily initialized (i.e on demand)
There is no order of initialization (Although load order can be
specified for eagerly loaded objects)
Init-method is called after all properties are injected<fxcontainer>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl“ lazy-
init=“false” load-order=“1” init-method=“someMethod”>
..
</fxobject>
</fxcontainer>
FxContainer: Sequences
<fxcontainer>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="movieCodes"> Primitive Sequence
<sequence>
<entry value=“1" />
<entry value="2" />
</sequence>
</property>
<property name="movies"> Object Sequence
<sequence>
<entry ref="movie1"/>
<entry ref="movie2"/>
</sequence>
</property>
</fxobject>
</fxcontainer>
FxContainer: Lists and Sets
<fxcontainer>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="movieList"> Object LIST
<list> (or <set>)
<entry ref="movie1"/>
<entry ref="movie2"/>
</list>
</property>
<property name="movieCodes"> Primitive LIST
<list valueClass=“java.lang.Integer”>
<entry value=“1" />
<entry value="2" />
</list>
</property>
</fxobject>
</fxcontainer>
FxObjects Lists and Sets
(Contd.)
Lists and Sets have to be initialized in their
parents with a new …..();
valueClass attribute
Optional in most cases
Reason: One cannot tell from the xml value
attributed if a list is Integer, String, BigDecimal
etc.
Needed for Java and JavaFX objects when
value attribute is specified in xml AND
List is not parameterized (always the case in JavaFX)
FxContainer: Maps
<fxcontainer>
<fxobject name="movieFinder"
class="org.fxobjects.samples.fxcontainer.MovieFinderImpl">
<property name="movieMap"> Object MAP
<map>
<entry keyRef=“stage1” valueRef="movie1"/>
</map>
</property>
<property name="movieCodes"> Primitive MAP
<map keyClass=“java.lang.String”
valueClass=“java.lang.Integer”>
<entry key=“Terminator 1” value=“1" />
<entry value=“Terminator 2" />
</map>
</property>
</fxobject>
</fxcontainer>
keyClass and valueClass are needed for Maps in JavaFX with key
and value specified. (since they cannot be parameterized) and
non-parameterized Maps in Java
FxContainer: Startup
Spring Like var loader = ClasspathXmlContainerLoader {
resourceLocation: "/org/fxobjects/samples/my.xml“
}
var container:FxContainer = loader.load();
var mvLister:MovieLister =
container.getFxObject("movieLister") as MovieLister;
FxContainer can be used the IoC container
with FxObjects or any other JavaFX
application independently
Just include 2 jars – fxcontainer.jar and
fxobjects-util.jar in classpath
FxObjects & FxContainer:
Roadmap
Links
Project site – https://fxobjects/dev.java.net
FxContainer is a subproject of FxObjects
Not a single person open source project
FxObjects and FxContainer developed and supported
by ObjectSource (http://www.objectsource.com)
Download, use, extend, redistribute, OEM
Discussion Forums on project site
Participation welcome
Post ideas, questions, concerns, comments
Contribute code
top related