Announcement Announcement Module
Collapse
No announcement yet.
Prototype bean constructor/factory runtime args Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Prototype bean constructor/factory runtime args

    I would like to send a runtime argument to a prototype bean. This appears to be in the box for the XMLBeanFactory class, having a getBean(String, Object[] args) method, but that method does not exist for an ApplicationContext.

    The reason is that I'm needing to create Hibernate SessionFactories at runtime and bind them to a schema that is only known at runtime. So, I would like to have my own implementation of LocalSessionFactoryBean that would essentially function the same, but instead create prototype SessionFactories that are bound to the appropriate schema, that is not known until runtime. Basically, this is to support the fact that we have multiple identical schemas, one for each of our customers, and my DAOs will accept the customer ID as a parameter, at which point they will request the appropriate SessionFactory, which will probalby be stored in a map keyed by customer ID, or created and bound to the appropriate schema if they're not in the map yet.

    I've been bouncing this around for a few days, and just can't think of a clean "Spring-erific" way to do it. I could always just make local method calls, bypassing the framework, but then I would have the ability to add interceptors to the intermediate objects.

    Any advice would be much appreciated.

  • #2
    getBean(String, Object[] args) is implemented by class AbstractBeanFactory. If you need to use this method from an ApplicationContext, consider using ClassPathXmlApplicationContext / FileSystemXmlApplicationContext for standalone applications or XmlWebApplicationContext for web applications. ContextLoaderListener, actually, registers a XmlWebApplicationContext in the servlet context.
    HTH

    Comment


    • #3
      BTW, is related to the SPR-334 'Dynamic Bean Arguments'
      issue in Spring's Jira?

      I looked at the source for AbstractBeanFactory for getBean, but could not quickly determine the relevance.

      Comment


      • #4
        Using Prototypes.

        I'm not sure exactly what you're trying to do; but I am using prototype beans in an application. What I am doing is:
        • implement BeanFactoryAware
          MyClass obj = (MyClass)beanFactory.getBean("beanName");

        At this point you can use the retrieved bean as a normal bean/object.

        Depending on what you mean by "send a runtime argument" you might need to look into either using Spring's AOP to wrap the calls; or extending one of Spring's ApplicationContexts and/or creating a BeanFactoryPostProcessor to add the functionality you want - take a look at the docs/source for the PropertyResourceConfigurer(s) to see this.

        Comment


        • #5
          ClassPath

          Originally posted by irbouho
          getBean(String, Object[] args) is implemented by class AbstractBeanFactory. If you need to use this method from an ApplicationContext, consider using ClassPathXmlApplicationContext / FileSystemXmlApplicationContext for standalone applications or XmlWebApplicationContext for web applications. ContextLoaderListener, actually, registers a XmlWebApplicationContext in the servlet context.
          HTH
          Regarding irbouho's suggestion, I don't see an implementation of getBean(String, Object[] args) in anything but AbstractBeanFactory, which is only available via XMLBeanFactory. I don't see a way to access a getBean method that takes an argument array via any of the application contexts. I also tried checking out the BeanFactory that is available via an ApplicationContext, but the returned object is not based upon AbstractBeanFactory, so the method is still not available.

          Comment


          • #6
            If your context is a ClassPathXmlApplicationContext / FileSystemXmlApplicationContext / XmlWebApplicationContext... use
            Code:
            AbstractBeanFactory beanFactory = (AbstractBeanFactory) context.getBeanFactory();
            MyBean bean = (MyBean) beanFactory.getBean(name, args);
            HTH

            Comment


            • #7
              Yep, that's it

              Originally posted by jbetancourt
              BTW, is related to the SPR-334 'Dynamic Bean Arguments'
              issue in Spring's Jira?

              I looked at the source for AbstractBeanFactory for getBean, but could not quickly determine the relevance.
              Yep, SPR-334 is definitely what I was hoping for. Right now, all I can come up with is an ugly hack of ThreadLocal objects and hot swap beans. I don't know why, but using ThreadLocals just smells bad to me, and I'm not even sure yet if it will work.

              Comment


              • #8
                Guaranteed?

                Originally posted by irbouho
                If your context is a ClassPathXmlApplicationContext / FileSystemXmlApplicationContext / XmlWebApplicationContext... use
                Code:
                AbstractBeanFactory beanFactory = (AbstractBeanFactory) context.getBeanFactory();
                MyBean bean = (MyBean) beanFactory.getBean(name, args);
                HTH
                Okay, that could work, but am I guaranteed that the returned object is always going to be based upon AbstractBeanFactory?

                Comment


                • #9
                  AFAIS from spring API, ClassPathXmlApplicationContext / FileSystemXmlApplicationContext / XmlWebApplicationContext extend AbstractRefreshableApplicationContext. The later has a DefaultListableBeanFactory beanFactoray property. Also DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory that extends AbstractBeanFactory. So, as of Spring 1.1.3, getBeanFactory, for these classes, should always return a AbstractBeanFactory subclass.
                  HTH

                  Comment


                  • #10
                    Originally posted by irbouho
                    If your context is a ClassPathXmlApplicationContext / FileSystemXmlApplicationContext / XmlWebApplicationContext... use
                    Code:
                    AbstractBeanFactory beanFactory = (AbstractBeanFactory) context.getBeanFactory();
                    MyBean bean = (MyBean) beanFactory.getBean(name, args);
                    HTH
                    How would look these parameters in applicationConext.xml file? I looked at spring reference but not found any example.

                    Comment


                    • #11
                      I wonder if perhaps there is some other way better than going under the hood of bean factory? For example, your LocalSessionFactoryBean subclass, say, MySessionFactoryBean could expose an extra property, schemaProvider, which is essentially a proxy interface that knows how to get the schema name at runtime.

                      Comment


                      • #12
                        I just added my vote to this. I had a similar idea that is in a different SPR (SPR-695, now marked as closed, with the code in the sandbox). Better to combine votes to get this functionality in Spring ASAP.

                        Comment


                        • #13
                          Originally posted by manifoldronin
                          I wonder if perhaps there is some other way better than going under the hood of bean factory? For example, your LocalSessionFactoryBean subclass, say, MySessionFactoryBean could expose an extra property, schemaProvider, which is essentially a proxy interface that knows how to get the schema name at runtime.
                          The approach I give here "Run-Time Dependency Injection": http://forum.springframework.org/showthread.php?t=14679
                          would help in this, or may be a starting point for an alternate solution.
                          Last edited by robyn; May 14th, 2006, 11:08 AM.

                          Comment


                          • #14
                            Having trouble getting to AbstractBeanFactory

                            So ultimately I need to / want to use getBean(myObject, MyObject.class, args), but we're using a BeanFactory derived from the ContextSingletonBeanFactoryLocator

                            Code:
                              protected BeanFactory createBeanFactory(String factoryName) {
                                BeanFactoryLocator bfl = ContextSingletonBeanFactoryLocator.getInstance();
                                BeanFactoryReference ref =	bfl.useBeanFactory(factoryName);
                                return ref.getFactory();
                              }
                            Given that I only have a BeanFactory and not an instance of ApplicationContext derived from say ClassPathXmlApplicationContext, how can I get a handle to the AbstractBeanFactory?

                            Thanks

                            Comment

                            Working...
                            X