blogger templates blogger widgets
This is part of a list of blog posts.
To browse the contents go to

Bind and lookup beans using resource-env-ref and custom factory class (tomcat)

Read about referenceables and object factory here.

We write a bean class "MyBean" that implements Referenceable.
import javax.naming.NamingException;
import javax.naming.Reference;
import javax.naming.Referenceable;
import javax.naming.StringRefAddr;

public class MyBean implements Referenceable{

 private String foo = "Default Foo";
 private int bar = 0;

 public String getFoo() {
  return (this.foo);
 }
 public void setFoo(String foo) {
  this.foo = foo;
 }
 public int getBar() {
  return (this.bar);
 }
 public void setBar(int bar) {
  this.bar = bar;
 }
 @Override
 public String toString() {
  return "MyBean [foo=" + foo + ", bar=" + bar + "]";
 }

 public Reference getReference() throws NamingException{
  String classname = MyBean.class.getName();
  StringRefAddr barref = new StringRefAddr("bar", Integer.toString(bar));
  StringRefAddr fooref = new StringRefAddr("foo", foo);

  String classfactoryname=MyBeanFactory.class.getName();
  Reference ref = new Reference(classname,classfactoryname,null);
  ref.add(barref);
  ref.add(fooref);
  return ref;
 }
}

We write the Factory class that helps to recreate "MyBean" objects from the Reference stored in context.

import java.util.Enumeration;
import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.Name;
import javax.naming.NamingException;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;

import sample.bean.MyBean;

public class MyBeanFactory implements ObjectFactory {

 public Object getObjectInstance(Object obj,
  Name name, Context nameCtx, Hashtable environment)
  throws NamingException {
  System.out.println("MyBeanFactory.getObjectInstance()");
  // Acquire an instance of our specified bean class
  MyBean bean = new MyBean();

  // Customize the bean properties from our attributes
  Reference ref = (Reference) obj;
  Enumeration addrs = ref.getAll();
  while (addrs.hasMoreElements()) {
   RefAddr addr = (RefAddr) addrs.nextElement();
   String attrName = addr.getType();
   String value = (String) addr.getContent();
   if (attrName.equals("foo")) {
    bean.setFoo(value);
   } else if (attrName.equals("bar")) {
    try {
     bean.setBar(Integer.parseInt(value)+100); //changed 
    } catch (NumberFormatException e) {
     throw new NamingException("Invalid 'bar' value " + value);
    }
   }
  }
  // Return the customized instance
  return (bean);
 }
}

No changes needs to be made to web.xml if you had run the previous example, else add the below entries in web.xml


<resource-env-ref>
    <description>Object factory for MyBean instances</description>
    <resource-env-ref-name>bean/MyBeanFactory</resource-env-ref-name>
    <resource-env-ref-type>sample.bean.MyBean</resource-env-ref-type>
</resource-env-ref>


Similarly, to change tomcat's resource factory add/modify this entry in context.xml.


<resource name="bean/MyBeanFactory" auth="Container" type="sample.bean.MyBean" factory="sample.bean.factory.MyBeanFactory" bar="23"/>


Servlet code:

try {
 Context initCxt =  new InitialContext();
 // one could use relative names into the sub-context
 Context envContext = (Context) initCxt.lookup("java:comp/env");
 MyBean myBean2 = (MyBean)envContext.lookup("bean/MyBeanFactory");
 // or we could do it in a single line
 //        MyBean myBean =  (MyBean)initCxt.lookup("java:comp/env/bean/MyBeanFactory");
 //        System.out.println(myBean.toString());
 System.out.println(myBean2.toString());
} catch (NamingException e) {
 e.printStackTrace();
}      

Output:
MyBeanFactory.getObjectInstance()
MyBean [foo=Default Foo, bar=123]

Continue reading: Difference between env-entry, resource-ref and resource-env-ref

No comments:

Post a Comment