diff --git a/jaxrs/resteasy-spring/src/main/java/org/jboss/resteasy/plugins/spring/SpringBeanProcessor.java b/jaxrs/resteasy-spring/src/main/java/org/jboss/resteasy/plugins/spring/SpringBeanProcessor.java
index 5557638499f..fb09d37f85e 100644
--- a/jaxrs/resteasy-spring/src/main/java/org/jboss/resteasy/plugins/spring/SpringBeanProcessor.java
+++ b/jaxrs/resteasy-spring/src/main/java/org/jboss/resteasy/plugins/spring/SpringBeanProcessor.java
@@ -1,37 +1,17 @@
package org.jboss.resteasy.plugins.spring;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.ws.rs.ext.MessageBodyReader;
-import javax.ws.rs.ext.MessageBodyWriter;
-import javax.ws.rs.ext.Provider;
-
import org.jboss.resteasy.core.Dispatcher;
-import org.jboss.resteasy.spi.HttpRequest;
-import org.jboss.resteasy.spi.HttpResponse;
-import org.jboss.resteasy.spi.PropertyInjector;
-import org.jboss.resteasy.spi.Registry;
-import org.jboss.resteasy.spi.ResteasyDeployment;
-import org.jboss.resteasy.spi.ResteasyProviderFactory;
+import org.jboss.resteasy.spi.*;
import org.jboss.resteasy.util.GetRestful;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValue;
+import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.annotation.Required;
-import org.springframework.beans.factory.config.BeanDefinition;
-import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
-import org.springframework.beans.factory.config.BeanPostProcessor;
-import org.springframework.beans.factory.config.BeanReference;
-import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.beans.factory.config.*;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationEvent;
@@ -39,6 +19,12 @@
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.util.ClassUtils;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Provider;
+import java.lang.reflect.Method;
+import java.util.*;
+
/**
*
* The processor will register any bean annotated with @Path or @Provider into
@@ -425,13 +411,46 @@ private static Class> getBeanClass(String name, BeanDefinition beanDef,
}
}
- for (Method method : getBeanClass(factoryClassName).getDeclaredMethods())
- {
- if (method.getName().equals(factoryMethodName))
- {
- return method.getReturnType();
- }
- }
+ final Class> beanClass = getBeanClass(factoryClassName);
+ final Method[] methods = beanClass.getDeclaredMethods();
+ for (Method method : methods) {
+ if (method.getName().equals(factoryMethodName)) {
+ return method.getReturnType();
+ }
+ }
+
+ /*
+ https://github.com/resteasy/Resteasy/issues/585
+
+ If we haven't found the correct factoryMethod using the previous method,
+ fallback to the default FactoryBean getObject method.
+
+ Case in which this tends to happen:
+
+ 1. A bean (Bean A) exists which provides factoryMethods for retrieving 1 or more other beans (Bean B, Bean C, ...)
+ example:
+ 2. Bean B is retrieved by telling Spring that the Factory-Bean is Bean A and that there is a method X to retrieve Bean B.
+ example:
+ 3. When resteasy has to inject Bean B it tries to lookup method X on Bean A instead of Bean B using the above code.
+
+ As a fix for this, we retrieve the return type for Bean A from the FactoryBean, which later on can be used to retrieve the other beans.
+
+ */
+ if (FactoryBean.class.isAssignableFrom(beanClass)) {
+ String defaultFactoryMethod = "getObject";
+ Class> returnType = null;
+ for (Method method : methods) {
+ if (method.getName().equals(defaultFactoryMethod)) {
+ returnType = method.getReturnType();
+ if (returnType != Object.class) {
+ break;
+ }
+ }
+ }
+ if (returnType != null) {
+ return returnType;
+ }
+ }
}
throw new IllegalStateException("could not find the type for bean named " + name);
diff --git a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBean.java b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBean.java
new file mode 100644
index 00000000000..ad2441d627c
--- /dev/null
+++ b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBean.java
@@ -0,0 +1,14 @@
+package org.jboss.resteasy.spring.beanprocessor;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: sgv
+ * Date: 23/10/14
+ * Time: 16:16
+ */
+public class MyBean {
+
+ public MyInnerBean getMyInnerBean() {
+ return new MyInnerBeanImpl();
+ }
+}
diff --git a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBeanFactoryBean.java b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBeanFactoryBean.java
new file mode 100644
index 00000000000..9690442661d
--- /dev/null
+++ b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyBeanFactoryBean.java
@@ -0,0 +1,27 @@
+package org.jboss.resteasy.spring.beanprocessor;
+
+import org.springframework.beans.factory.FactoryBean;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: sgv
+ * Date: 23/10/14
+ * Time: 16:15
+ */
+public class MyBeanFactoryBean implements FactoryBean {
+
+ @Override
+ public MyBean getObject() throws Exception {
+ return new MyBean();
+ }
+
+ @Override
+ public Class> getObjectType() {
+ return MyBean.class;
+ }
+
+ @Override
+ public boolean isSingleton() {
+ return true;
+ }
+}
diff --git a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBean.java b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBean.java
new file mode 100644
index 00000000000..6321c5443fe
--- /dev/null
+++ b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBean.java
@@ -0,0 +1,10 @@
+package org.jboss.resteasy.spring.beanprocessor;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: sgv
+ * Date: 24/10/14
+ * Time: 8:44
+ */
+public interface MyInnerBean {
+}
diff --git a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBeanImpl.java b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBeanImpl.java
new file mode 100644
index 00000000000..2cb313f6b09
--- /dev/null
+++ b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/spring/beanprocessor/MyInnerBeanImpl.java
@@ -0,0 +1,10 @@
+package org.jboss.resteasy.spring.beanprocessor;
+
+/**
+ * Created with IntelliJ IDEA.
+ * User: sgv
+ * Date: 24/10/14
+ * Time: 8:45
+ */
+public class MyInnerBeanImpl implements MyInnerBean {
+}
diff --git a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/springmvc/test/spring/RequestScopedBeanTest.java b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/springmvc/test/spring/RequestScopedBeanTest.java
index 9e1afa66c25..60c1f3a267b 100644
--- a/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/springmvc/test/spring/RequestScopedBeanTest.java
+++ b/jaxrs/resteasy-spring/src/test/java/org/jboss/resteasy/springmvc/test/spring/RequestScopedBeanTest.java
@@ -5,10 +5,9 @@
import org.jboss.resteasy.core.ValueInjector;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;
-import org.jboss.resteasy.spi.PropertyInjector;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.jboss.resteasy.spi.metadata.Parameter;
-import org.jboss.resteasy.spi.metadata.ResourceClass;
+import org.jboss.resteasy.spring.beanprocessor.MyInnerBean;
import org.jboss.resteasy.springmvc.tjws.TJWSEmbeddedSpringMVCServer;
import org.jboss.resteasy.test.TestPortProvider;
import org.jboss.resteasy.util.FindAnnotation;
@@ -18,6 +17,7 @@
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import javax.ws.rs.GET;
@@ -110,6 +110,9 @@ public void setConfigured(String configured)
}
}
+ @Autowired
+ private MyInnerBean myInnerBean;
+
@Path("/")
public static class TestBeanResource
{
diff --git a/jaxrs/resteasy-spring/src/test/resources/spring-request-scope-test-server.xml b/jaxrs/resteasy-spring/src/test/resources/spring-request-scope-test-server.xml
index b6874da1fe6..de5eb2d8eb7 100644
--- a/jaxrs/resteasy-spring/src/test/resources/spring-request-scope-test-server.xml
+++ b/jaxrs/resteasy-spring/src/test/resources/spring-request-scope-test-server.xml
@@ -2,15 +2,20 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
-
+
-
+
-
+
+
+
+
+