3 Replies Latest reply on Apr 9, 2008 4:59 AM by Scott Stark

    GenericBeanFactory and install methods

    Scott Stark Master

      An issue I have with creating a custom BeanFactoryMetaData instance that models an ejb container is that I want to have the ejb interceptors added to the ejb bean context via install methods. The custom BeanFactoryMetaData (org.jboss.test.kernel.deployment.support.container.BeanContextFactory) creates 4+ BeanMetaDatas:

      1. GenericBeanFactory(BeanContext) - is the bean factory for creating the bean component consisting of:
      2 - bean context
      3 - + bean instance
      4 - + 0 or more bean interceptors

      The BeanMetaData for the interceptors wants to install the interceptor bean into the BeanContext by calling the addInterceptor method. However, the BeanMetaData for the BeanContext if the GenericBeanFactory. There is no notion of the GenericBeanFactory acting as a proxy for the BeanContext instances in terms of install/uninstall callbacks.

      Its not obvious how this can be supported in the current impl as the GenericBeanFactory.createBean instances are themselves not mc beans with a name that could be used with the interceptor install metadata.

      Ideas on how to do this, add support for it?

      See the org.jboss.test.kernel.deployment.test.BeanContainerUsageTestCaseMD.testComponentBeanFactory for the current wiring.

        • 1. Re: GenericBeanFactory and install methods
          Scott Stark Master

          Thinking about this more, talking with Carlo, what we really need is a MetaGenericBeanFactory:

          interface MetaBeanFactory extends BeanFactory
          {
           BeanMetaData createBeanMetaData();
          }
          


          whose contract is to create the BeanMetaData for the bean and then install that into the mc when createBean() is called. This way create lifecycle events like PostConstruct can be delegated to the mc as well as the install callbacks.

          • 2. Re: GenericBeanFactory and install methods
            Scott Stark Master

            And going through this again, its probably nothing more than another pattern on top of existing mc notions:

            interface ComponentFactory
            {
             List<String> createComponent(String baseName);
            }
            
            class GenericComponentFactory implements KernelControllerContextAware
            {
             BeanMetaDataFactory componentsFactory;
             int compID;
            
             List<String> createComponent(String baseName)
             {
             int nextID = incCompID();
             KernelController controller = ...;
             List<BeanMetaData> compBeans = componentsFactory.getBeans();
             for(BeanMetaData bmd : compBeans)
             {
             String beanName = baseName + bmd.getName() + "#" + nextID;
             controller.install(beanName, bmd); // Ignoring there is no install taking the bean name
             compNames.add(beanName);
             }
             return compNames;
             }
            }
            


            The ComponentFactory/GenericComponentFactory would be used similar to how BeanFactory/GenericBeanFactory are currently.


            • 3. Re: GenericBeanFactory and install methods
              Scott Stark Master

              Which has now expanded to:

              /**
               * Factory for the BeanMetaData describing component instances.
               * @author Scott.Stark@jboss.org
               * @version $Revision:$
               */
              public interface ComponentBeanMetaDataFactory
              {
               /**
               * Create the beans that will be created together as a component.
               *
               * @param baseName - base name used to derive unique bean name
               * @param compID - component id used to derive unique bean name
               * @param nameBuilder - transformer used to derive unique bean name from baseName/compID
               * @param visitor - optional visitor that may augment BeanMetaData
               * @return list of beans describing the component
               */
               public List<BeanMetaData> getBeans(String baseName, long compID,
               ComponentNameBuilder nameBuilder, ComponentVisitor visitor);
              }
              
              /**
               * A factory for creating a collection of related mc beans based on a
               * template of BeanMetaData[] from a BeanMetaDataFactory.
               *
               * @author Scott.Stark@jboss.org
               * @version $Revision:$
               */
              public interface ComponentFactory<T>
              {
               /**
               * the factory which defines template BeanMetaData[] for the components
               * @return the BeanMetaDataFactory defining the component beans
               */
               public ComponentBeanMetaDataFactory getFactory();
              
               /**
               * Install a collection of mc beans based on the factory metadata.
               *
               * @param baseName - the base bean name used in conjuction wth the factory.getBeans()
               * BeanMetaData instances getName() to build the unique bean name:
               * baseName + bmd.getName() + "#" + compID;
               * @return the component context instance information.
               * @throws Throwable - on failure to install the component beans
               */
               public ComponentInstance<T> createComponents(String baseName)
               throws Throwable;
              
               /**
               * Extract the unique component id from a component bean name.
               * @param name - a name previously returned from createComponents.
               * @return the component id portion of the name
               * @throws NumberFormatException - if name is not a valild bean component
               * name with a component id.
               */
               public long getComponentID(String name) throws NumberFormatException;
              
               /**
               * Uninstall the component beans for the given instance
               * @param instance - the ComponentInstance previously returned from createComponents
               * @throws Exception - on failure to uninstall the component beans
               */
               public void destroyComponents(ComponentInstance<T> instance)
               throws Exception;
              }
              
              /**
               * The component context instance. This is the bean that acts as the container
               * for the component bean instances.
               *
               * @author Scott.Stark@jboss.org
               * @version $Revision:$
               */
              public interface ComponentInstance<T>
              {
               /**
               * Get the name of the bean for the component context instance
               * @return
               */
               public String getContextName();
               /**
               * Get the component bean names
               * @return
               */
               public List<String> getComponentNames();
               /**
               * Get the id associated with this component
               * @return
               */
               public long getComponentID();
               /**
               * Get the component context instance
               * @return
               */
               public T getContext();
              
              }
              
              /**
               * Abstraction for building/parsing component names
               *
               * @author Scott.Stark@jboss.org
               * @version $Revision:$
               */
              public interface ComponentNameBuilder
              {
               /**
               * Create a globally unique mc bean name
               * @param baseName - base name used to derive unique bean name
               * @param compName - the component name used to derive unique bean name
               * @param compID - component id used to derive unique bean name
               * @return the unique mc bean name
               */
               public String buildName(String baseName, String compName, long compID);
               /**
               * Parse a mc bean name for the component id
               * @param name - the mc bean name
               * @return the component id
               * @throws NumberFormatException
               */
               public long getComponentID(String name) throws NumberFormatException;
              }
              
              /**
               * A component bean factory visitor plugin that allows for extension of the
               * bean metadata produced by the factory.
               *
               * @author Scott.Stark@jboss.org
               * @version $Revision:$
               */
              public interface ComponentVisitor
              {
               /**
               * Visit callback to allow for augmentation of a components bean metadata.
               * @param builder - the bean metadata build facade to augment the metadata
               * @param baseName - the bean base name
               * @param componentName - the bean component name
               * @param compID - the bean component id
               */
               void visit(BeanMetaDataBuilder builder, String baseName,
               String componentName, long compID);
              
              }