DATACMNS-669 - Register QuerydslPredicateArgumentResolver as bean.
If no QuerydslBinderCustomizer is configured on @QuerydslPredicate specifically, we now also consider the domain types repository as candidate for binding customization. The lookup algorithm for explicitly configured customizers has been refined to try to find a bean in the BeanFactory first, resorting to on-the-fly creation eventually. QuerydslPredicateArgumentResolver is now registered as a lazily initialized bean and its usage is guarded by checking presence of Querydsl itself. The according test needs to do some reflection in order to stay out of trouble when types are loaded by different class loaders required to hide certain types. Original pull request: #132.
This commit is contained in:
committed by
Oliver Gierke
parent
cccfa5e5c5
commit
64c8549db4
@@ -23,6 +23,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.data.geo.format.DistanceFormatter;
|
||||
import org.springframework.data.geo.format.PointFormatter;
|
||||
@@ -68,6 +69,17 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
|
||||
return new SortHandlerMethodArgumentResolver();
|
||||
}
|
||||
|
||||
/**
|
||||
* Default QuerydslPredicateArgumentResolver.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Bean
|
||||
@Lazy
|
||||
public QuerydslPredicateArgumentResolver querydslPredicateArgumentResolver() {
|
||||
return new QuerydslPredicateArgumentResolver(conversionService.getObject());
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addFormatters(org.springframework.format.FormatterRegistry)
|
||||
@@ -100,7 +112,7 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
|
||||
argumentResolvers.add(pageableResolver());
|
||||
|
||||
if (QueryDslUtils.QUERY_DSL_PRESENT) {
|
||||
argumentResolvers.add(new QuerydslPredicateArgumentResolver(conversionService.getObject()));
|
||||
argumentResolvers.add(querydslPredicateArgumentResolver());
|
||||
}
|
||||
|
||||
ProxyingHandlerMethodArgumentResolver resolver = new ProxyingHandlerMethodArgumentResolver(
|
||||
@@ -110,4 +122,5 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
|
||||
|
||||
argumentResolvers.add(resolver);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import java.util.Map.Entry;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
@@ -27,6 +28,7 @@ import org.springframework.core.MethodParameter;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.support.DefaultConversionService;
|
||||
import org.springframework.data.querydsl.SimpleEntityPathResolver;
|
||||
import org.springframework.data.repository.support.Repositories;
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
@@ -53,6 +55,8 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR
|
||||
|
||||
private AutowireCapableBeanFactory beanFactory;
|
||||
|
||||
private Repositories repositories;
|
||||
|
||||
/**
|
||||
* Creates a new {@link QuerydslPredicateArgumentResolver} using the given {@link ConversionService}.
|
||||
*
|
||||
@@ -69,7 +73,9 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR
|
||||
*/
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
|
||||
this.beanFactory = applicationContext.getAutowireCapableBeanFactory();
|
||||
this.repositories = new Repositories(applicationContext);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -127,17 +133,48 @@ public class QuerydslPredicateArgumentResolver implements HandlerMethodArgumentR
|
||||
|
||||
EntityPath<?> path = SimpleEntityPathResolver.INSTANCE.createPath(domainType);
|
||||
|
||||
QuerydslBinderCustomizer customizer = findCustomizerForDomainType(annotation, domainType);
|
||||
|
||||
QuerydslBindings bindings = new QuerydslBindings();
|
||||
|
||||
if (annotation == null || annotation.bindings().equals(QuerydslBinderCustomizer.class)) {
|
||||
return bindings;
|
||||
if (customizer != null) {
|
||||
customizer.customize(bindings, path);
|
||||
}
|
||||
|
||||
Class<? extends QuerydslBinderCustomizer> type = annotation.bindings();
|
||||
QuerydslBinderCustomizer<EntityPath<?>> customizer = beanFactory != null ? beanFactory.createBean(type)
|
||||
: BeanUtils.instantiateClass(type);
|
||||
customizer.customize(bindings, path);
|
||||
|
||||
return bindings;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private QuerydslBinderCustomizer<EntityPath<?>> findCustomizerForDomainType(QuerydslPredicate annotation,
|
||||
Class<?> domainType) {
|
||||
|
||||
if (annotation == null || (annotation != null && annotation.bindings().equals(QuerydslBinderCustomizer.class))) {
|
||||
if (repositories != null && repositories.hasRepositoryFor(domainType)) {
|
||||
|
||||
Object repository = this.repositories.getRepositoryFor(domainType);
|
||||
if (repository instanceof QuerydslBinderCustomizer) {
|
||||
return (QuerydslBinderCustomizer<EntityPath<?>>) repository;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
return createQuerydslBinderCustomizer(annotation.bindings());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
private QuerydslBinderCustomizer<EntityPath<?>> createQuerydslBinderCustomizer(
|
||||
Class<? extends QuerydslBinderCustomizer> type) {
|
||||
|
||||
if (beanFactory == null) {
|
||||
return BeanUtils.instantiateClass(type);
|
||||
}
|
||||
|
||||
try {
|
||||
return beanFactory.getBean(type);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
|
||||
}
|
||||
|
||||
return beanFactory.createBean(type);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user