GWT homepage
Overview
Get started
Tutorials
Docs
Resources
Make GWT Better
Terms
Download
Java Doc
Creative Commons Attribution 3.0 License.
Overview
Coding Basics
Introduction
Organize Projects
Compile & Debug
Client-side
JRE Compatibility
Ajax Communication
History Mechanism
Formatting
Delayed Logic
Working with JSON
Working with XML
JavaScript: JSNI
Overlay Types
Deferred Binding
Build User Interfaces
Html5 Support
Test with JUnit
Deploy
Advanced Topics
Reference
FAQ
Glossary
Search
Deferred
Deferred binding is a feature of the GWT compiler that works by generating many versions of code at compile time, only one of which needs to be loaded by a particular client during bootstrapping at runtime. Each version is generated on a per browser basis, along with any other axis that your application defines or uses. For example, if you were to internationalize your application using GWT’s Internationalization module, the GWT compiler would generate various versions of your application per browser environment, such as “Firefox in English”, “Firefox in French”, “Internet Explorer in English”, etc… As a result, the deployed JavaScript code is compact and quicker to download than hand coded JavaScript, containing only the code and resources it needs for a particular browser environment.
Deferred Binding Benefits
Defining Deferred Binding Rules
Directives in Module XML files
Deferred Binding Using Replacement
Example Class Hierarchy using Replacement
Deferred Binding using Generators
Generator Configuration in Module XML
Generator Implementation
Deferred Binding Benefits
Deferred Binding is a technique used by the GWT compiler to create and select a specific implementation of a class based on a set of parameters. In essence, deferred binding is the GWT answer to Java reflection. It allows the GWT developer to produce several variations of their applications custom to each browser environment and have only one of them actually downloaded and executed in the browser.
Deferred binding has several benefits:
Reduces the size of the generated JavaScript code that a client will need to download by only including the code needed to run a particular browser/locale instance (used by the Internationalization module)
Saves development time by automatically generating code to implement an interface or create a proxy class (used by the GWT RPC module)
Since the implementations are pre-bound at compile time, there is no run-time penalty to look up an implementation in a data structure as with dynamic binding or using virtual functions.
Some parts of the toolkit make implicit use of deferred binding, that is, they use the technique as a part of their implementation, but it is not visible to the user of the API. For example, many widgets and panels as well as the DOM class use this technique to implement browser specific logic. Other GWT features require the API user to explicity invoke deferred binding by designing classes that follow specific rules and instantiating instances of the classes with GWT.create(Class), including GWT RPC and I18N.
As a user of the GWT, you may never need to create a new interface that uses deferred binding. If you follow the instructions in the guide for creating internationalized applications or GWT RPC calls you will be using deferred binding, but you will not have to actually write any browser dependent or locale dependent code.
The rest of the deferred binding section describes how to create new rules and classes using deferred binding. If you are new to the toolkit or only intend to use pre-packaged widgets, you will probably want to skip on to the next topic. If you are interested in programming entirely new widgets from the ground up or other functionality that requires cross-browser dependent code, the next sections should be of interest.
Defining Deferred Binding Rules
There are two ways in which types can be replaced via deferred binding:
Replacement: A type is replaced with another depending on a set of configurable rules.
Code generation: A type is substituted by the result of invoking a code generator at compile time.
Directives in Module XML files
The deferred binding mechanism is completely configurable and does not require editing the GWT distributed source code. Deferred binding is configured through the UnableToCompleteException if for any reason
* it cannot provide a substitute class
*
* @return the name of a subclass to substitute for the requested class, or
* return null to cause the requested type itself to be
* used
*
*/
public String generate(TreeLogger logger, GeneratorContext ctx,
String requestedClass) throws UnableToCompleteException {
TypeOracle typeOracle = ctx.getTypeOracle();
assert (typeOracle != null);
JClassType remoteService = typeOracle.findType(requestedClass);
if (remoteService == null) {
logger.log(TreeLogger.ERROR, "Unable to find metadata for type '"
+ requestedClass + "'", null);
throw new UnableToCompleteException();
}
if (remoteService.isInterface() == null) {
logger.log(TreeLogger.ERROR, remoteService.getQualifiedSourceName()
+ " is not an interface", null);
throw new UnableToCompleteException();
}
ProxyCreator proxyCreator = new ProxyCreator(remoteService);
TreeLogger proxyLogger = logger.branch(TreeLogger.DEBUG,
"Generating client proxy for remote service interface '"
+ remoteService.getQualifiedSourceName() + "'", null);
return proxyCreator.create(proxyLogger, ctx);
}
}
The typeOracle is an object that contains information about the Java code that has already been parsed that the generator may need to consult. In this case, the generate() method checks it arguments and the passes off the bulk of the work to another class (ProxyCreator).