From c49f8357b67f10b9ca1b13b9421c28610d5ebc84 Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Fri, 19 Jun 2015 13:05:56 +0200 Subject: [PATCH] DATACMNS-718 - Class loader improvements in ProxyProjectionFactory. ProxyProjectionFactory now implements ResourceLoaderAware to be able to use the class loader used by the framework. SpringDataWebConfiguration now forwards the Application context as ResourceLoader through ProxyingHandlerMethodArgumentResolver into the target factory. --- .../projection/ProxyProjectionFactory.java | 21 ++++++++++++++++--- ...ProxyingHandlerMethodArgumentResolver.java | 14 ++++++++++++- .../config/SpringDataWebConfiguration.java | 7 ++++++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java index 649ad688e..d44945562 100644 --- a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java +++ b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java @@ -27,7 +27,10 @@ import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.ProxyFactory; import org.springframework.beans.BeanUtils; +import org.springframework.context.ResourceLoaderAware; +import org.springframework.core.io.ResourceLoader; import org.springframework.util.Assert; +import org.springframework.util.ClassUtils; /** * A {@link ProjectionFactory} to create JDK proxies to back interfaces and handle method invocations on them. By @@ -39,11 +42,22 @@ import org.springframework.util.Assert; * @see SpelAwareProxyProjectionFactory * @since 1.10 */ -class ProxyProjectionFactory implements ProjectionFactory { +class ProxyProjectionFactory implements ProjectionFactory, ResourceLoaderAware { private static final boolean IS_JAVA_8 = org.springframework.util.ClassUtils.isPresent("java.util.Optional", ProxyProjectionFactory.class.getClassLoader()); + private ResourceLoader resourceLoader; + + /* + * (non-Javadoc) + * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader) + */ + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.resourceLoader = resourceLoader; + } + /* * (non-Javadoc) * @see org.springframework.data.rest.core.projection.ProjectionFactory#createProjection(java.lang.Object, java.lang.Class) @@ -71,7 +85,8 @@ class ProxyProjectionFactory implements ProjectionFactory { factory.addAdvice(new TargetAwareMethodInterceptor(source.getClass())); factory.addAdvice(getMethodInterceptor(source, projectionType)); - return (T) factory.getProxy(getClass().getClassLoader()); + return (T) factory + .getProxy(resourceLoader == null ? ClassUtils.getDefaultClassLoader() : resourceLoader.getClassLoader()); } /* @@ -141,7 +156,7 @@ class ProxyProjectionFactory implements ProjectionFactory { /** * Returns whether the given {@link PropertyDescriptor} describes an input property for the projection, i.e. a * property that needs to be present on the source to be able to create reasonable projections for the type the - * descritor was looked up on. + * descriptor was looked up on. * * @param descriptor will never be {@literal null}. * @return diff --git a/src/main/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolver.java b/src/main/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolver.java index 2f736f0e0..32e46fe5f 100644 --- a/src/main/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolver.java +++ b/src/main/java/org/springframework/data/web/ProxyingHandlerMethodArgumentResolver.java @@ -19,8 +19,10 @@ import org.springframework.beans.BeansException; import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.context.ResourceLoaderAware; import org.springframework.core.MethodParameter; import org.springframework.core.convert.ConversionService; +import org.springframework.core.io.ResourceLoader; import org.springframework.data.projection.SpelAwareProxyProjectionFactory; import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.support.WebDataBinderFactory; @@ -34,7 +36,8 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver; * @author Oliver Gierke * @since 1.10 */ -public class ProxyingHandlerMethodArgumentResolver extends ModelAttributeMethodProcessor implements BeanFactoryAware { +public class ProxyingHandlerMethodArgumentResolver extends ModelAttributeMethodProcessor + implements BeanFactoryAware, ResourceLoaderAware { private final SpelAwareProxyProjectionFactory proxyFactory; private final ConversionService conversionService; @@ -61,6 +64,15 @@ public class ProxyingHandlerMethodArgumentResolver extends ModelAttributeMethodP this.proxyFactory.setBeanFactory(beanFactory); } + /* + * (non-Javadoc) + * @see org.springframework.context.ResourceLoaderAware#setResourceLoader(org.springframework.core.io.ResourceLoader) + */ + @Override + public void setResourceLoader(ResourceLoader resourceLoader) { + this.proxyFactory.setResourceLoader(resourceLoader); + } + /* * (non-Javadoc) * @see org.springframework.web.method.support.HandlerMethodArgumentResolver#supportsParameter(org.springframework.core.MethodParameter) diff --git a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java index 413679654..644304c00 100644 --- a/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java +++ b/src/main/java/org/springframework/data/web/config/SpringDataWebConfiguration.java @@ -97,6 +97,11 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter { argumentResolvers.add(sortResolver()); argumentResolvers.add(pageableResolver()); - argumentResolvers.add(new ProxyingHandlerMethodArgumentResolver(conversionService.getObject())); + ProxyingHandlerMethodArgumentResolver resolver = new ProxyingHandlerMethodArgumentResolver( + conversionService.getObject()); + resolver.setBeanFactory(context); + resolver.setResourceLoader(context); + + argumentResolvers.add(resolver); } }