Search This Blog

Tuesday, 28 February 2012

Loading the Configuration

In our previous posts we created an XML based configuration file that provided the Bean Factory information on the beans to be created. The XmlBeanFactory class takes a resource instance as a part of its constructor parameter.
package com.runner;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.InputStreamResource;
import org.springframework.core.io.Resource;

import com.start.HelloWorldMessanger;

public class Client {

    public static BeanFactory getFromClassPath() {
        Resource res = new ClassPathResource("beans.xml");
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(res);
        return xmlBeanFactory;
    }

    public static BeanFactory getFromFile() {
        Resource res = new FileSystemResource("D:\\beans.xml");
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(res);
        return xmlBeanFactory;
    }

    public static BeanFactory getFromInputStream() throws FileNotFoundException {
        Resource res = new InputStreamResource(
                new FileInputStream(
                        new File("D:\\beans.xml")));
        XmlBeanFactory xmlBeanFactory = new XmlBeanFactory(res);
        return xmlBeanFactory;
    }

    public static void main(String[] args) throws FileNotFoundException {
        BeanFactory beanFactory = getFromClassPath();
        testBeanFactory(beanFactory);
        System.out.println("Testing for File system");
        beanFactory = getFromFile();
        testBeanFactory(beanFactory);
        System.out.println("Testing from Input Stream");
        beanFactory = getFromInputStream();
        testBeanFactory(beanFactory);

    }

    private static void testBeanFactory(BeanFactory beanFactory) {
        HelloWorldMessanger messager = (HelloWorldMessanger) beanFactory
                .getBean("messager");
        System.out.println(messager.getMessage());
    }

}
In the above class I created a Beanfactory using various Resources.
  1. The ClassPathResource searches the application class path for the specified file. 
  2. The FileSystemResource reads in an xml file from the file system. 
  3. The InputStreamResource is capable of reading  in the xml configuration from any input stream . 
On executing the class the output is as below:
Hello World
Testing for File system
Hello World
Testing from Input Stream
Feb 4, 2012 3:02:48 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [beans.xml]
Feb 4, 2012 3:02:49 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from file [D:\beans.xml]
Feb 4, 2012 3:02:49 PM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from resource loaded through InputStream
Exception in thread "main" org.springframework.beans.factory.BeanDefinitionStoreException: 
Passed-in Resource [resource loaded through InputStream] contains an open 
stream: cannot determine validation mode automatically. Either pass in a 
Resource that is able to create fresh streams, or explicitly specify the 
validationMode on your XmlBeanDefinitionReader instance.
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.detectValidationMode(XmlBeanDefinitionReader.java:449)
 at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.getValidationModeForResource(XmlBeanDefinitionReader.java:430)
The file system and the class path resources worked fine. However I was not able to get the more generic File Stream to work.
Other Resource Implementations available include:
  1. ByteArrayResource
  2. DescriptiveResource
  3. PortletContextResource, 
  4. ServletContextResource, 
  5. UrlResource
Although the BeanFactory is loading each of the Configurations as a part of its constructor it does not instantiate any of the beans immediately. The  beans are lazily loaded by the factory - meaning  they are created only when they are needed. We shall see more of this later.

HelloWorldMessanger messager = (HelloWorldMessanger) beanFactory.getBean("messager");
on the call of the getBean() method the Beanfactory will create the bean and start wiring its properties.

No comments:

Post a Comment