Skip to content

Commit bebac8e

Browse files
committed
GRAILS-11323 Fallback for autowire properties optimization
1 parent 4f4aafa commit bebac8e

File tree

2 files changed

+62
-1
lines changed

2 files changed

+62
-1
lines changed

grails-core/src/main/groovy/org/codehaus/groovy/grails/commons/spring/ReloadAwareAutowireCapableBeanFactory.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,19 @@ public void autowireBeanProperties(Object existingBean, int autowireMode, boolea
183183
if (DISABLE_AUTOWIRE_BY_NAME_OPTIMIZATIONS || dependencyCheck || existingBean instanceof Aware) {
184184
super.autowireBeanProperties(existingBean, autowireMode, dependencyCheck);
185185
} else {
186-
populateBeanInAutowireByName(existingBean);
186+
try {
187+
populateBeanInAutowireByName(existingBean);
188+
} catch (Exception e) {
189+
logger.error("Bean couldn't be autowired using grails optimization: " + e.getMessage());
190+
logger.error("Retrying using spring autowire");
191+
192+
// Remove the cache value in order to asure there is no problem with a previous value
193+
Class<?> beanClass = ClassUtils.getUserClass(existingBean.getClass());
194+
autowireableBeanPropsCacheForClass.remove(beanClass);
195+
196+
// Calls the spring method
197+
super.autowireBeanProperties(existingBean, autowireMode, dependencyCheck);
198+
}
187199
}
188200
} else {
189201
super.autowireBeanProperties(existingBean, autowireMode, dependencyCheck);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package org.codehaus.groovy.grails.commons.spring
2+
3+
import spock.lang.Specification
4+
5+
import org.springframework.util.ClassUtils
6+
import javassist.util.proxy.*
7+
import org.springframework.beans.*
8+
import java.beans.PropertyDescriptor
9+
import org.springframework.beans.factory.support.GenericBeanDefinition
10+
11+
class ReloadAwareAutowireCapableBeanFactorySpec extends Specification {
12+
static int AUTOWIRE_BY_NAME = 1
13+
14+
void "Test factory bean cache fallback"() {
15+
setup: "Setup the factory bean"
16+
def factoryBean = new ReloadAwareAutowireCapableBeanFactory()
17+
18+
and: "Bean to be inspected for autowire"
19+
def existingBean = new TestObject()
20+
21+
and: "Creates a Javassist proxy"
22+
def proxyFactory = new ProxyFactory()
23+
proxyFactory.setSuperclass(TestObject.class)
24+
def clazz = proxyFactory.createClass()
25+
def proxy = clazz.newInstance([:])
26+
27+
and: "Saves the property 'setAutowireProperty' and 'getAutowireProperty' inside the properties cache"
28+
def writeMethod = clazz.getMethod("setAutowireProperty", Object.class)
29+
def readMethod = clazz.getMethod("getAutowireProperty")
30+
def autowireableBeanProps = ['autowireProperty': new PropertyDescriptor('autowireProperty', readMethod, writeMethod)]
31+
32+
and: "Put the proxy inside the properties cache"
33+
def beanDefinition = new GenericBeanDefinition()
34+
beanDefinition.beanClass = String.class
35+
beanDefinition.autowireCandidate = true
36+
factoryBean.registerBeanDefinition("autowireProperty", beanDefinition)
37+
factoryBean.autowireableBeanPropsCacheForClass.put(TestObject.class, autowireableBeanProps)
38+
39+
when: "We try to autowire a normal bean but the cache is populated with the proxy"
40+
factoryBean.autowireBeanProperties(existingBean, 1, false)
41+
42+
then:
43+
notThrown(Exception)
44+
}
45+
}
46+
47+
class TestObject{
48+
def autowireProperty
49+
}

0 commit comments

Comments
 (0)