Commits

Anonymous committed e35cfd5

Adding a new property to force the usage of the configured autowire strategy
WW-2479

git-svn-id: http://svn.opensymphony.com/svn/xwork/trunk@1831e221344d-f017-0410-9bd5-d282ab1896d7

Comments (0)

Files changed (2)

src/java/com/opensymphony/xwork2/spring/SpringObjectFactory.java

     protected int autowireStrategy = AutowireCapableBeanFactory.AUTOWIRE_BY_NAME;
     private Map classes = new HashMap();
     private boolean useClassCache = true;
+    private boolean alwaysRespectAutowireStrategy = false;
 
     @Inject(value="applicationContextPath",required=false)
     public void setApplicationContextPath(String ctx) {
         Object bean;
 
         try {
-            bean = autoWiringFactory.autowire(clazz, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
+            // Decide to follow autowire strategy or use the legacy approach which mixes injection strategies
+            if (alwaysRespectAutowireStrategy) {
+                // Leave the creation up to Spring
+                bean = autoWiringFactory.createBean(clazz, autowireStrategy, false);
+                injectApplicationContext(bean);
+                return injectInternalBeans(bean);
+            } else {
+                bean = autoWiringFactory.autowire(clazz, AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR, false);
+                bean = autoWiringFactory.applyBeanPostProcessorsBeforeInitialization(bean, bean.getClass().getName());
+                // We don't need to call the init-method since one won't be registered.
+                bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean, bean.getClass().getName());
+                return autoWireBean(bean, autoWiringFactory);
+            }
         } catch (UnsatisfiedDependencyException e) {
             // Fall back
-            bean = super.buildBean(clazz, extraContext);
+            return autoWireBean(super.buildBean(clazz, extraContext), autoWiringFactory);
         }
-
-        bean = autoWiringFactory.applyBeanPostProcessorsBeforeInitialization(bean, bean.getClass().getName());
-        // We don't need to call the init-method since one won't be registered.
-        bean = autoWiringFactory.applyBeanPostProcessorsAfterInitialization(bean, bean.getClass().getName());
-        return autoWireBean(bean, autoWiringFactory);
     }
 
     public Object autoWireBean(Object bean) {
             autoWiringFactory.autowireBeanProperties(bean,
                     autowireStrategy, false);
         }
-        if (bean instanceof ApplicationContextAware) {
-            ((ApplicationContextAware) bean).setApplicationContext(appContext);
-        }
-        
+        injectApplicationContext(bean);
+
         injectInternalBeans(bean);
 
         return bean;
     }
 
+    private void injectApplicationContext(Object bean) {
+        if (bean instanceof ApplicationContextAware) {
+            ((ApplicationContextAware) bean).setApplicationContext(appContext);
+        }
+    }
+
     public Class getClassInstance(String className) throws ClassNotFoundException {
         Class clazz = null;
         if (useClassCache) {
     public void setUseClassCache(boolean useClassCache) {
         this.useClassCache = useClassCache;
     }
+
+    /**
+     * Determines if the autowire strategy is always followed when creating beans
+     *
+     * @param alwaysRespectAutowireStrategy True if the strategy is always used
+     */
+    public void setAlwaysRespectAutowireStrategy(boolean alwaysRespectAutowireStrategy) {
+        this.alwaysRespectAutowireStrategy = alwaysRespectAutowireStrategy;
+    }
 }

src/test/com/opensymphony/xwork2/spring/SpringObjectFactoryTest.java

 import org.springframework.beans.BeansException;
 import org.springframework.beans.MutablePropertyValues;
 import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
+import org.springframework.beans.factory.BeanCreationException;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.support.StaticApplicationContext;
 
         objectFactory = (SpringObjectFactory) container.getInstance(ObjectFactory.class);
         objectFactory.setApplicationContext(sac);
+        objectFactory.setAlwaysRespectAutowireStrategy(false);
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        sac = null;
+        objectFactory = null;
     }
 
     public void testFallsBackToDefaultObjectFactoryActionSearching() throws Exception {
 
     public void testShouldUseConstructorBasedInjectionWhenCreatingABeanFromAClassName() throws Exception {
         SpringObjectFactory factory = (SpringObjectFactory) objectFactory;
+        objectFactory.setAlwaysRespectAutowireStrategy(false);
         sac.registerSingleton("actionBean", SimpleAction.class, new MutablePropertyValues());
 
         ConstructorBean bean = (ConstructorBean) factory.buildBean(ConstructorBean.class, null);
         assertNotNull("Action should have been added via DI", bean.getAction());
     }
 
+    public void testShouldUseAutowireStrategyWhenCreatingABeanFromAClassName_constructor() throws Exception {
+        objectFactory.setAlwaysRespectAutowireStrategy(true);
+        objectFactory.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
+        sac.registerSingleton("actionBean", SimpleAction.class, new MutablePropertyValues());
+
+        ConstructorBean bean = (ConstructorBean) objectFactory.buildBean(ConstructorBean.class, null);
+
+        assertNotNull("Bean should not be null", bean);
+        assertNotNull("Action should have been added via DI", bean.getAction());
+    }
+
+    public void testShouldUseAutowireStrategyWhenCreatingABeanFromAClassName_setterByType() throws Exception {
+        objectFactory.setAlwaysRespectAutowireStrategy(true);
+
+        objectFactory.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE);
+        sac.registerSingleton("actionBean", SimpleAction.class, new MutablePropertyValues());
+
+        SetterByTypeBean bean = (SetterByTypeBean) objectFactory.buildBean(SetterByTypeBean.class, null);
+
+        assertNotNull("Bean should not be null", bean);
+        assertNotNull("Action should have been added via DI", bean.getAction());
+    }
+
+    public void testShouldUseAutowireStrategyWhenCreatingABeanFromAClassName_setterByName() throws Exception {
+        objectFactory.setAlwaysRespectAutowireStrategy(true);
+
+        objectFactory.setAutowireStrategy(AutowireCapableBeanFactory.AUTOWIRE_BY_NAME);
+        sac.registerSingleton("actionBean", SimpleAction.class, new MutablePropertyValues());
+
+        SetterByNameBean bean = (SetterByNameBean) objectFactory.buildBean(SetterByNameBean.class, null);
+
+        assertNotNull("Bean should not be null", bean);
+        assertNotNull("Action should have been added via DI", bean.getActionBean());
+    }
+
     public void testFallBackToDefaultObjectFactoryWhenTheCConstructorDIIsAmbiguous() throws Exception {
-        SpringObjectFactory factory = (SpringObjectFactory) objectFactory;
+        objectFactory.setAlwaysRespectAutowireStrategy(true);
         sac.registerSingleton("firstActionBean", SimpleAction.class, new MutablePropertyValues());
         sac.registerSingleton("secondActionBean", SimpleAction.class, new MutablePropertyValues());
 
-        ConstructorBean bean = (ConstructorBean) factory.buildBean(ConstructorBean.class, null);
+        ConstructorBean bean = (ConstructorBean) objectFactory.buildBean(ConstructorBean.class, null);
 
         assertNotNull("Bean should have been created using default constructor", bean);
         assertNull("Not expecting this to have been set", bean.getAction());
         }
     }
 
+    public static class SetterByNameBean {
+        private SimpleAction action;
+
+        public SetterByNameBean() {
+            // Empty constructor
+        }
+
+        public SimpleAction getActionBean() {
+            return action;
+        }
+
+        public void setActionBean(SimpleAction action) {
+            this.action = action;
+        }
+    }
+
+    public static class SetterByTypeBean {
+        private SimpleAction action;
+
+        public SetterByTypeBean() {
+            // Empty constructor
+        }
+
+        public SimpleAction getAction() {
+            return action;
+        }
+
+        public void setAction(SimpleAction action) {
+            this.action = action;
+        }
+    }
+
     public static class ConstructorAction implements Action {
         private SimpleAction action;