DATACMNS-744 - Removed strong dependency to Querydsl in web support.

Moved all Querydsl related bean definitions and customizations to a dedicated configuration class that only gets included if Querydsl is on the classpath.

Extracted a QuerydslActivator for use in Spring Data REST, which uses HateoasAwareSpringDataWebConfiguration via inheritance, not via @EnableSpringDataWebSupport.

Previously, we exposed a QuerydslBindingsFactory as bean method return type which breaks Spring bootstrap even if it's lazy due to its references to Querydsl types.

Related tickets: DATACMNS-669.
This commit is contained in:
Oliver Gierke
2015-08-04 01:30:19 +02:00
parent b9125ee83d
commit 9afb5777e9
3 changed files with 100 additions and 32 deletions

View File

@@ -33,6 +33,7 @@ import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.data.querydsl.QueryDslUtils;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.util.ClassUtils;
@@ -70,7 +71,8 @@ import org.springframework.util.ClassUtils;
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.ANNOTATION_TYPE })
@Inherited
@Import(EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector.class)
@Import({ EnableSpringDataWebSupport.SpringDataWebConfigurationImportSelector.class,
EnableSpringDataWebSupport.QuerydslActivator.class })
public @interface EnableSpringDataWebSupport {
/**
@@ -81,7 +83,8 @@ public @interface EnableSpringDataWebSupport {
*
* @author Oliver Gierke
*/
class SpringDataWebConfigurationImportSelector implements ImportSelector, EnvironmentAware, ResourceLoaderAware {
static class SpringDataWebConfigurationImportSelector
implements ImportSelector, EnvironmentAware, ResourceLoaderAware {
// Don't make final to allow test cases faking this to false
private static boolean HATEOAS_PRESENT = ClassUtils.isPresent("org.springframework.hateoas.Link", null);
@@ -135,4 +138,25 @@ public @interface EnableSpringDataWebSupport {
return imports.toArray(new String[imports.size()]);
}
}
/**
* Import selector to register {@link QuerydslWebConfiguration} as configuration class if Querydsl is on the
* classpath.
*
* @author Oliver Gierke
* @soundtrack Anika Nilles - Chary Life
* @since 1.11
*/
static class QuerydslActivator implements ImportSelector {
/*
* (non-Javadoc)
* @see org.springframework.context.annotation.ImportSelector#selectImports(org.springframework.core.type.AnnotationMetadata)
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return QueryDslUtils.QUERY_DSL_PRESENT ? new String[] { QuerydslWebConfiguration.class.getName() }
: new String[0];
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.web.config;
import java.util.List;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mysema.query.types.Predicate;
/**
* Querydsl-specific web configuration for Spring Data. Registers a {@link HandlerMethodArgumentResolver} that builds up
* {@link Predicate}s from web requests.
*
* @author Oliver Gierke
* @since 1.11
* @soundtrack Anika Nilles - Alter Ego
*/
@Configuration
public class QuerydslWebConfiguration extends WebMvcConfigurerAdapter {
@Autowired @Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService;
/**
* Default {@link QuerydslPredicateArgumentResolver} to create Querydsl {@link Predicate} instances for Spring MVC
* controller methods.
*
* @return
*/
@Lazy
@Bean
public QuerydslPredicateArgumentResolver querydslPredicateArgumentResolver() {
return new QuerydslPredicateArgumentResolver(querydslBindingsFactory(), conversionService.getObject());
}
@Lazy
@Bean
public QuerydslBindingsFactory querydslBindingsFactory() {
return new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
}
/*
* (non-Javadoc)
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addArgumentResolvers(java.util.List)
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(0, querydslPredicateArgumentResolver());
}
}

View File

@@ -23,25 +23,18 @@ 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;
import org.springframework.data.querydsl.QueryDslUtils;
import org.springframework.data.querydsl.SimpleEntityPathResolver;
import org.springframework.data.querydsl.binding.QuerydslBindingsFactory;
import org.springframework.data.repository.support.DomainClassConverter;
import org.springframework.data.web.PageableHandlerMethodArgumentResolver;
import org.springframework.data.web.ProxyingHandlerMethodArgumentResolver;
import org.springframework.data.web.SortHandlerMethodArgumentResolver;
import org.springframework.data.web.querydsl.QuerydslPredicateArgumentResolver;
import org.springframework.format.FormatterRegistry;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.mysema.query.types.Predicate;
/**
* Configuration class to register {@link PageableHandlerMethodArgumentResolver},
* {@link SortHandlerMethodArgumentResolver} and {@link DomainClassConverter}.
@@ -73,24 +66,6 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
return new SortHandlerMethodArgumentResolver();
}
/**
* Default {@link QuerydslPredicateArgumentResolver} to create Querydsl {@link Predicate} instances for Spring MVC
* controller methods.
*
* @return
*/
@Lazy
@Bean
public HandlerMethodArgumentResolver querydslPredicateArgumentResolver() {
return new QuerydslPredicateArgumentResolver(querydslBindingsFactory(), conversionService.getObject());
}
@Lazy
@Bean
public QuerydslBindingsFactory querydslBindingsFactory() {
return new QuerydslBindingsFactory(SimpleEntityPathResolver.INSTANCE);
}
/*
* (non-Javadoc)
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addFormatters(org.springframework.format.FormatterRegistry)
@@ -122,10 +97,6 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
argumentResolvers.add(sortResolver());
argumentResolvers.add(pageableResolver());
if (QueryDslUtils.QUERY_DSL_PRESENT) {
argumentResolvers.add(querydslPredicateArgumentResolver());
}
ProxyingHandlerMethodArgumentResolver resolver = new ProxyingHandlerMethodArgumentResolver(
conversionService.getObject());
resolver.setBeanFactory(context);
@@ -133,5 +104,4 @@ public class SpringDataWebConfiguration extends WebMvcConfigurerAdapter {
argumentResolvers.add(resolver);
}
}