Skip to content

Commit e311472

Browse files
committed
GRAILS-6790 - register the auto proxy creator in the “root” application context so that any configuration made by plugins/apps apply to our proxy creator.
1 parent 349300d commit e311472

File tree

4 files changed

+83
-15
lines changed

4 files changed

+83
-15
lines changed

src/java/org/codehaus/groovy/grails/plugins/CoreGrailsPlugin.groovy

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,9 @@ import org.codehaus.groovy.grails.support.proxy.DefaultProxyHandler
3535
import org.springframework.beans.factory.config.CustomEditorConfigurer
3636
import org.springframework.beans.factory.config.MethodInvokingFactoryBean
3737
import org.springframework.beans.factory.xml.XmlBeanFactory
38+
import org.springframework.aop.config.AopConfigUtils
3839
import org.springframework.core.io.Resource
40+
import org.springframework.beans.factory.support.GenericBeanDefinition
3941
import org.codehaus.groovy.grails.aop.framework.autoproxy.GroovyAwareAspectJAwareAdvisorAutoProxyCreator
4042

4143
/**
@@ -56,15 +58,18 @@ class CoreGrailsPlugin {
5658
addBeanFactoryPostProcessor(new MapBasedSmartPropertyOverrideConfigurer(application))
5759
addBeanFactoryPostProcessor(new GrailsPlaceholderConfigurer())
5860

59-
// replace AutoProxy advisor with Groovy aware one
6061
def grailsConfig = application.config.grails
6162
def springConfig = grailsConfig.spring
62-
if(springConfig.disable.aspectj.autoweaving) {
63-
"org.springframework.aop.config.internalAutoProxyCreator"(GroovyAwareInfrastructureAdvisorAutoProxyCreator)
64-
}
65-
else {
66-
"org.springframework.aop.config.internalAutoProxyCreator"(GroovyAwareAspectJAwareAdvisorAutoProxyCreator)
67-
}
63+
64+
// configure a Groovy aware AutoProxy advisor
65+
// we need to do this on the parent context to allow
66+
// plugins/apps to affect it while creating/configing beans
67+
// See GRAILS-6790
68+
def aspectJDisabled = springConfig.disable.aspectj.autoweaving
69+
def proxyCreatorType = aspectJDisabled ? GroovyAwareInfrastructureAdvisorAutoProxyCreator : GroovyAwareAspectJAwareAdvisorAutoProxyCreator
70+
def proxyCreatorDefinition = new GenericBeanDefinition()
71+
proxyCreatorDefinition.beanClass = proxyCreatorType
72+
parentCtx.beanFactory.registerBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME, proxyCreatorDefinition)
6873

6974
// Allow the use of Spring annotated components
7075
context.'annotation-config'()

src/java/org/codehaus/groovy/grails/support/MockApplicationContext.java

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import org.springframework.util.AntPathMatcher;
5151
import org.springframework.util.PathMatcher;
5252
import org.springframework.web.context.WebApplicationContext;
53+
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
5354

5455
public class MockApplicationContext extends GroovyObjectSupport implements WebApplicationContext {
5556

@@ -59,6 +60,7 @@ public class MockApplicationContext extends GroovyObjectSupport implements WebAp
5960
List<String> ignoredClassLocations = new ArrayList<String>();
6061
PathMatcher pathMatcher = new AntPathMatcher();
6162
ServletContext servletContext = new MockServletContext();
63+
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
6264

6365
public void registerMockBean(String name, Object instance) {
6466
beans.put(name, instance);
@@ -113,6 +115,10 @@ public ApplicationContext getParent() {
113115
throw new UnsupportedOperationException("Method not supported by implementation");
114116
}
115117

118+
BeanFactory getBeanFactory() {
119+
return beanFactory;
120+
}
121+
116122
public String getId() {
117123
return "MockApplicationContext";
118124
}
@@ -193,26 +199,30 @@ public Map<String, Object> getBeansWithAnnotation(Class<? extends Annotation> an
193199

194200
public Object getBean(String name) throws BeansException {
195201
if (!beans.containsKey(name)) {
196-
throw new NoSuchBeanDefinitionException(name);
202+
if (!beanFactory.containsBean(name)) {
203+
throw new NoSuchBeanDefinitionException(name);
204+
} else {
205+
return beanFactory.getBean(name);
206+
}
207+
} else {
208+
return beans.get(name);
197209
}
198-
return beans.get(name);
199210
}
200211

201212
@SuppressWarnings("unchecked")
202213
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
203-
if (!beans.containsKey(name)) {
204-
throw new NoSuchBeanDefinitionException( name);
205-
}
214+
Object bean = getBean(name);
206215

207-
if (requiredType != null && !requiredType.isAssignableFrom(beans.get(name).getClass())) {
216+
if (requiredType != null && !requiredType.isAssignableFrom(bean.getClass())) {
208217
throw new NoSuchBeanDefinitionException(name);
209218
}
210219

211-
return (T)beans.get(name);
220+
return (T)bean;
212221
}
213222

214223
public <T> T getBean(Class<T> tClass) throws BeansException {
215224
final Map<String, T> map = getBeansOfType(tClass);
225+
map.putAll(beanFactory.getBeansOfType(tClass));
216226
if (map.isEmpty()) {
217227
throw new NoSuchBeanDefinitionException(tClass, "No bean found for type: " + tClass.getName());
218228
}
@@ -329,7 +339,7 @@ public boolean containsLocalBean(String arg0) {
329339
}
330340

331341
public AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException {
332-
return new DefaultListableBeanFactory();
342+
return beanFactory;
333343
}
334344
public ClassLoader getClassLoader() {
335345
return getClass().getClassLoader();

src/test/org/codehaus/groovy/grails/plugins/CoreGrailsPluginTests.groovy

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import org.codehaus.groovy.grails.commons.test.AbstractGrailsMockTests
66
import org.codehaus.groovy.grails.aop.framework.autoproxy.GroovyAwareAspectJAwareAdvisorAutoProxyCreator
77
import org.codehaus.groovy.grails.aop.framework.autoproxy.GroovyAwareInfrastructureAdvisorAutoProxyCreator
88

9+
import grails.spring.BeanBuilder
10+
911
class CoreGrailsPluginTests extends AbstractGrailsMockTests {
1012

1113
void testCorePlugin() {
@@ -115,4 +117,37 @@ class CoreGrailsPluginTests extends AbstractGrailsMockTests {
115117
assertEquals(1, appCtx.getBean('someTransactionalService').i)
116118
assertEquals(2, appCtx.getBean('nonTransactionalService').i)
117119
}
120+
121+
// See GRAILS-6790
122+
void testAopConfigurationIsEffective() {
123+
def pluginClass = gcl.loadClass("org.codehaus.groovy.grails.plugins.CoreGrailsPlugin")
124+
def plugin = new DefaultGrailsPlugin(pluginClass, ga)
125+
def springConfig = new WebRuntimeSpringConfiguration(ctx)
126+
127+
plugin.doWithRuntimeConfiguration(springConfig)
128+
129+
def bb = new BeanBuilder(ctx, springConfig, null)
130+
bb.beans {
131+
xmlns aop: "http://www.springframework.org/schema/aop"
132+
133+
aop.config("proxy-target-class": true) {
134+
135+
aspect(id: "myPlainJavaAspect-id", ref: "myAspect") {
136+
"before" method: "myBeforeAdvice", pointcut: "execution(* myMethod1(..))"
137+
}
138+
}
139+
140+
myInterfaceImpl(CoreGrailsPluginTestsAopConfig.MyInterfaceImpl)
141+
myAspect(CoreGrailsPluginTestsAopConfig.MyAspect)
142+
}
143+
144+
def appCtx = springConfig.getApplicationContext()
145+
def bean = appCtx.getBean("myInterfaceImpl")
146+
147+
// if we can call the following method, then the proxy was class based
148+
// because 'myMethod2' is not on the only interface this implements
149+
bean.myMethod2()
150+
}
151+
152+
118153
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.codehaus.groovy.grails.plugins;
2+
3+
// Used in CoreGrailsPluginTests#testAopConfigurationIsEffective
4+
// Must be Java because Groovy classes are always proxy by class
5+
class CoreGrailsPluginTestsAopConfig {
6+
static public class MyAspect {
7+
public void myBeforeAdvice() {}
8+
}
9+
10+
static public interface MyInterface {
11+
void myMethod1();
12+
}
13+
14+
static public class MyInterfaceImpl implements MyInterface {
15+
public void myMethod1() {}
16+
public void myMethod2() {}
17+
}
18+
}

0 commit comments

Comments
 (0)