Announcement Announcement Module
Collapse
No announcement yet.
Run-Time Dependency Injection (RTDI) idea. Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Run-Time Dependency Injection (RTDI) idea.

    I thought I'd see if a very simple approach toward RTDI is possible.

    My idea is that the interval used by BeanPostProcessor could be used to invoke an injector on a bean. To not require any new interfaces on the bean, the injection hookup is done with an approach similar to proxy use. But, really its just a Visitor pattern.

    Code:
     
    /**
     * RunTime Dependency Injector interface.
     * The Visitor of the Visitor pattern.
     * 
     * May 3, 2005
     * @author JBETANCOURT
     *
     */
    public interface RTDI {
        /**
         * @param bean
         */
        void inject(Object bean);
    
    }
    
    
    /**
     * A BeanPostProcessor for invoking an object that supplies run-time
     * configuration to another object. 
     * This uses the Visitor pattern. But, see existing Spring API
     * for approaches such as&#58;<p/>
     * 
     * @see org.springframework.beans.factory.config.ServiceLocatorFactoryBean
     * @see org.springframework.beans.factory.support.AbstractBeanFactory.getBean&#40;...&#41;
     * @see org.springframework.beans.factory.config.ServiceCreationFactoryBean &#40;in
     *      Sandbox&#41;
     * @see org.springframework.beans.factory.config.BeanPostProcessor.html
     * <p/>
     * NOTE&#58; TO SAVE SPACE LEFT OUT CLASS DETAILS
     * <p/>
     *
     *
     * Example context definition&#58;
     * <pre>
     * <beans>
     *
     *     <bean id="clientOne" class="Client"/>        
     *     <bean id="injectorOne" class="Injector"/>
     *         
     *     <bean id="rtdiBean" class="RTDIPostProcessor">
     *         <property name="beanNames">
     *             <list>
     *                 <value>clientOne</value>                
     *             </list>            
     *         </property> 
     *         <property name="injectorNames">
     *             <list>
     *                 <value>injectorOne</value>                
     *             </list>               
     *         </property>
     *                
     *     </bean>
     *
     * </beans>
     * </pre>
     *
     * 
     * May 3, 2005
     * 
     * @author JBETANCOURT
     *  
     */
    public class RTDIPostProcessor implements BeanPostProcessor,
            ApplicationContextAware &#123;
        /** which beans will be post processed */
        List beanNames; // 
    
        /** list of RTDI bean names that will apply the post processing. */
        List injectorNames;
    
        /** where we pull the injector from */
        private ApplicationContext ctx;
        
        public Object postProcessBeforeInitialization&#40;Object bean, String beanName&#41;
                throws BeansException &#123;
    
            if &#40;injectorNames.isEmpty&#40;&#41; || beanNames.isEmpty&#40;&#41;&#41; &#123;
                return bean;
            &#125;
    
            if &#40;beanNames.contains&#40;beanName&#41;&#41; &#123;
                for &#40;Iterator iter = injectorNames.iterator&#40;&#41;; iter.hasNext&#40;&#41;;&#41; &#123;
                    String visitorName = &#40;String&#41; iter.next&#40;&#41;;
                    RTDI visitor = &#40;RTDI&#41; ctx.getBean&#40;visitorName&#41;;
                    
                    // in this invocation the visitor must determine the actual rtti of bean.
                    visitor.inject&#40;bean&#41;;
    
                    //  // alternativly, use reflection to invoke.
                    //  Method method = BeanUtils.findDeclaredMethod&#40;
                    //          visitor.getClass&#40;&#41;, INJECT_METHOD_NAME, new Class&#91;&#93; &#123; bean
                    //                  .getClass&#40;&#41; &#125;&#41;;
                    //  // TODO&#58; fault handling ...  
                    //  try &#123;
                    //      method.invoke&#40;visitor, new Object&#91;&#93; &#123; bean &#125;&#41;;
                    //  &#125; catch &#40;InvocationTargetException e&#41; &#123;
                    //      throw e.getCause&#40;&#41;;
                    //  &#125;
                &#125;
    
            &#125;
    
            return bean;
        &#125;
    
    &#125;
    It works, at least a simple unit test proves it, but it still doesn't really solve the RTDI problem for me. I can't use it, and I'm sure there are better Springish ways to go about it, but maybe someone will find it useful or it may inspire a better approach.

  • #2
    Yes, I've seen people use a similar approach to inject a logger or to simulate callbacks from other frameworks such as Avalon.

    What exactly are you trying to achieve? It would be interesting to know the exact requirements, which this doesn't quite meet...

    Comment


    • #3
      I was going to try to use this approach to inject table names into prototype jdbc dao objects, in liu of having to change what I have too much and also look at your suggestion to use the JdbcTemplate. But, the simplicity just hides some issues, like, though the rtdi object can inject at the right time, how do they get the data they should inject? Seems I am back to square one.

      Comment


      • #4
        But, the simplicity just hides some issues, like, though the rtdi object can inject at the right time, how do they get the data they should inject?
        Yes, in this case, the problem is how you specify the data, not how it's injected. I think runtime injection does make sense for things that are known only at runtime, but your case is really static metadata that could be handled equally well (or badly) with normal injection.

        In your scenario I would definitely use JdbcTemplate. I tend to use it a lot myself, and I've done lots of dynamic SQL with it.

        Comment

        Working...
        X