Using Proxied classes as BlazeDS Destinations

Posted by Swarn Dhaliwal, Ph.D.

Aug 16, 2010 9:30:00 AM Open Source, BlazeDs, Java, Code Generation, Web 2.0

In BlazeDS, the mechanism for instantiating Java Classes implementing messaging destinations seems to be hardwired into flex.messaging.factories.JavaFactory class. It will be nice to be able to provide a CustomJavaFactory such that the destinations can be created using an application specific way. For instance, one use case may be implementing Destinations as Dynamic Proxies which can inject all kinds of behaviors into the methods calls made by blazeds before they are handled by the actual destination class. As an example you might want to add current user information to all the requests before they get handled by the actual destination class. To accomplish this kind of behavior we had to modify the BlazeDs source and recompile it. The source code for the the classes involved in our implementation is given below. First to avoid reimplementing functionality BlazeDs already provides, the flex.messaging.factories.JavaFactory class shipped with BlazeDs needs an extension point such that subclasses can override the functionality responsible for instantiating the Destination classes. The following snippet of code from flex.messaging.factories.JavaFactory class shows this code modification.
    /**
     * This method is called when we initialize the definition of an instance which
     * will be looked up by this factory. It should validate that the properties
     * supplied are valid to define an instance. Any valid properties used for
     * this configuration must be accessed to avoid warnings about unused
     * configuration elements. If your factory is only used for application
     * scoped components, you do not need to implement this method as the lookup
     * method itself can be used to validate its configuration.
     */
    public FactoryInstance createFactoryInstance(String id, ConfigMap properties)
    {
        //Code responsible for instantiation extracted into an ovveridable 
      // method.
        JavaFactoryInstance instance = instantiateFactoryInstance(id, properties);
       ……..
       ///rest of the code in the method removed for brevity.
      return instance;
    }
 
    /**
       extension point for allowing subclasses to override behavior of the factory.
    */
    protected JavaFactoryInstance instantiateFactoryInstance(String id, ConfigMap properties) {
        return new JavaFactoryInstance(this, id, properties);
    }
 
//Custom Java Factory — A custom JavaFactory that subclasses the JavaFactory above and 
// delegates destination instantiation to CustomJavaFactoryInstance class. 
import flex.messaging.config.ConfigMap;
import flex.messaging.factories.JavaFactory;
import flex.messaging.factories.JavaFactoryInstance;
import org.apache.log4j.Logger;
/**
 * This class ..
 *
 * @author Swarn S. Dhaliwal
 * @version 1.0 Mar 26, 2010
 */
public class CustomJavaFactory extends JavaFactory {
    private transient static final Logger log = Logger.getLogger(CustomJavaFactory.class);
    @Override
    protected JavaFactoryInstance instantiateFactoryInstance(String id, ConfigMap properties) {
        return new CustomJavaFactoryInstance(this, id, properties);
    }
}
// CustomJavaFactoryInstance — Custom class responsible for creating the Destination instances. This is where a proxied Destination instance can be provided.
import flex.messaging.config.ConfigMap;
import flex.messaging.factories.JavaFactory;
import flex.messaging.factories.JavaFactoryInstance;
import flex.messaging.util.ClassUtil;
import org.apache.log4j.Logger;
/**
 * This class ..
 *
 * @author Swarn S. Dhaliwal
 * @version 1.0 Mar 26, 2010
 */
public class CustomJavaFactoryInstance extends JavaFactoryInstance {
    private transient static final Logger log = Logger.getLogger(CustomJavaFactoryInstance.class);
    /**
     * Constructs a JavaFactoryInstance, assigning its factory, id,
     * and properties.
     *
     * @param factory The JavaFactory that created this instance.
     * @param id The id for the JavaFactoryInstance.
     * @param properties The properties for the JavaFactoryInstance.
     */
    public CustomJavaFactoryInstance(JavaFactory factory, String id, ConfigMap properties) {
        super(factory, id, properties);
    }
    @Override
    public Object createInstance() {
        log.debug(“CustomJavaFactoryInstance”);
        Object inst = ClassUtil.createDefaultInstance(getInstanceClass(), null);
        return FlexReportServiceFactory.createProxiedInstance(inst);
    }
}
//ReportsDynamicConfigService — This class is need to bootstrap the Custom Java Factory into BlazeDs at initialization.
 
import flex.messaging.config.ConfigMap;
import flex.messaging.services.AbstractBootstrapService;
import flex.messaging.services.RemotingService;
import flex.messaging.services.remoting.RemotingDestination;
import org.apache.log4j.Logger;
/**
 * This class ..
 *
 * @author Swarn S. Dhaliwal
 * @version 1.0 Mar 26, 2010
 */
public class ReportsDynamicConfigService extends AbstractBootstrapService {
    private transient static final Logger log = Logger.getLogger(ReportsDynamicConfigService.class);
    @Override
    public void initialize(String id, ConfigMap properties) {
        log.info(“Initializing ReportsDynamicConfigService”);
        RemotingService remotingService = (RemotingService) getMessageBroker().getService(“remoting-service”);
        RemotingDestination destination = (RemotingDestination) remotingService.getDestination(“reportService”);
        destination.setFactory(new CustomJavaFactory());
    }
    @Override
    public void start() {
        log.info(“Start ReportsDynamicConfigService”);
    }
    @Override
    public void stop() {
        log.info(“Stop ReportsDynamicConfigService”);
    }
}
//snippet from services-config.xml showing use of Dynamic Config Service for bootstrapping the Custom Factory 
<services>
     <service-include file-path=”remoting-config.xml”/>
     <service-include file-path=”proxy-config.xml”/>
     <service-include file-path=”messaging-config.xml”/> 
     <service class=”mil.navy.housing.reports.flex.ReportsDynamicConfigService”id=”reportService1″/>
</services>
The DynamicConfigService above allows customizing configuration of destination service for individual destinations. For instance, a specific factory may be specified for each destination or a class of destinations thus creating a very flexible Destination instantiation mechanism. 

Posted by Swarn Dhaliwal, Ph.D.

Dr. Dhaliwal is an experienced SUN Certified Java Developer with a master's degree in Computer Science and more than 8 years of comprehensive Java implementation experience using a variety of J2EE technologies.

    

Posts by Topic

see all
Request a Complimentary Docker Consultation

An Open View

Vizuri Blog

Subscribing to our blog is a great way to stay up to date with the latest information from Vizuri, as well as our strategic partners. We focus on providing a range of content that is practically useful and relevant from both a technical and business perspective.

We promise to respect your privacy.

×