DATACMNS-1736 - Use BeanFactory lookup in configuration classes instead of intercepted local bean methods.

We now use @Configuration(proxyBeanMethods = false) and use BeanFactory bean lookups to avoid CGlib proxy creation.

Using Spring's BeanProvider.getIfUnique(…) instead of catching NoSuchBeanDefinitionException.
This commit is contained in:
Mark Paluch
2020-05-29 10:10:07 +02:00
committed by Oliver Drotbohm
parent c85b524508
commit c10072c96f
4 changed files with 51 additions and 33 deletions

View File

@@ -37,10 +37,13 @@ import org.springframework.web.method.support.HandlerMethodArgumentResolver;
* @author Nick Williams
* @author Ben Hale
* @author Vedran Pavic
* @author Mark Paluch
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfiguration {
private final ApplicationContext context;
/**
* @param context must not be {@literal null}.
* @param conversionService must not be {@literal null}.
@@ -48,6 +51,7 @@ public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfigu
public HateoasAwareSpringDataWebConfiguration(ApplicationContext context,
@Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService) {
super(context, conversionService);
this.context = context;
}
/*
@@ -59,7 +63,7 @@ public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfigu
public HateoasPageableHandlerMethodArgumentResolver pageableResolver() {
HateoasPageableHandlerMethodArgumentResolver pageableResolver = new HateoasPageableHandlerMethodArgumentResolver(
sortResolver());
getSortResolverBean());
customizePageableResolver(pageableResolver);
return pageableResolver;
}
@@ -79,12 +83,12 @@ public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfigu
@Bean
public PagedResourcesAssembler<?> pagedResourcesAssembler() {
return new PagedResourcesAssembler<>(pageableResolver(), null);
return new PagedResourcesAssembler<>(getPageableResolverBean(), null);
}
@Bean
public PagedResourcesAssemblerArgumentResolver pagedResourcesAssemblerArgumentResolver() {
return new PagedResourcesAssemblerArgumentResolver(pageableResolver(), null);
return new PagedResourcesAssemblerArgumentResolver(getPageableResolverBean(), null);
}
/*
@@ -94,6 +98,23 @@ public class HateoasAwareSpringDataWebConfiguration extends SpringDataWebConfigu
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
super.addArgumentResolvers(argumentResolvers);
argumentResolvers.add(pagedResourcesAssemblerArgumentResolver());
argumentResolvers
.add(context.getBean("pagedResourcesAssemblerArgumentResolver", PagedResourcesAssemblerArgumentResolver.class));
}
/*
* (non-Javadoc)
* @see org.springframework.data.web.config.SpringDataWebConfiguration#getSortResolverBean()
*/
protected HateoasSortHandlerMethodArgumentResolver getSortResolverBean() {
return context.getBean("sortResolver", HateoasSortHandlerMethodArgumentResolver.class);
}
/*
* (non-Javadoc)
* @see org.springframework.data.web.config.SpringDataWebConfiguration#getPageableResolverBean()
*/
protected HateoasPageableHandlerMethodArgumentResolver getPageableResolverBean() {
return context.getBean("pageableResolver", HateoasPageableHandlerMethodArgumentResolver.class);
}
}

View File

@@ -38,9 +38,10 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
* {@link ProxyingHandlerMethodArgumentResolver}.
*
* @author Oliver Gierke
* @author Mark Paluch
* @soundtrack Apparat With Soap & Skin - Goodbye (Dark Theme Song - https://www.youtube.com/watch?v=66VnOdk6oto)
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public class ProjectingArgumentResolverRegistrar {
/**

View File

@@ -18,6 +18,7 @@ package org.springframework.data.web.config;
import java.util.List;
import java.util.Optional;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
@@ -40,14 +41,16 @@ import com.querydsl.core.types.Predicate;
* {@link Predicate}s from web requests.
*
* @author Oliver Gierke
* @author Mark Paluch
* @since 1.11
* @soundtrack Anika Nilles - Alter Ego
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public class QuerydslWebConfiguration implements WebMvcConfigurer {
@Autowired @Qualifier("mvcConversionService") ObjectFactory<ConversionService> conversionService;
@Autowired ObjectProvider<EntityPathResolver> resolver;
@Autowired BeanFactory beanFactory;
/**
* Default {@link QuerydslPredicateArgumentResolver} to create Querydsl {@link Predicate} instances for Spring MVC
@@ -58,7 +61,9 @@ public class QuerydslWebConfiguration implements WebMvcConfigurer {
@Lazy
@Bean
public QuerydslPredicateArgumentResolver querydslPredicateArgumentResolver() {
return new QuerydslPredicateArgumentResolver(querydslBindingsFactory(), Optional.of(conversionService.getObject()));
return new QuerydslPredicateArgumentResolver(
beanFactory.getBean("querydslBindingsFactory", QuerydslBindingsFactory.class),
Optional.of(conversionService.getObject()));
}
@Lazy
@@ -73,6 +78,7 @@ public class QuerydslWebConfiguration implements WebMvcConfigurer {
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(0, querydslPredicateArgumentResolver());
argumentResolvers.add(0,
beanFactory.getBean("querydslPredicateArgumentResolver", QuerydslPredicateArgumentResolver.class));
}
}

View File

@@ -17,10 +17,8 @@ package org.springframework.data.web.config;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;
import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
@@ -55,8 +53,9 @@ import com.fasterxml.jackson.databind.ObjectMapper;
* @author Oliver Gierke
* @author Vedran Pavic
* @author Jens Schauder
* @author Mark Paluch
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLoaderAware {
private final ApplicationContext context;
@@ -93,7 +92,7 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo
public PageableHandlerMethodArgumentResolver pageableResolver() {
PageableHandlerMethodArgumentResolver pageableResolver = //
new PageableHandlerMethodArgumentResolver(sortResolver());
new PageableHandlerMethodArgumentResolver(getSortResolverBean());
customizePageableResolver(pageableResolver);
return pageableResolver;
}
@@ -137,8 +136,8 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(sortResolver());
argumentResolvers.add(pageableResolver());
argumentResolvers.add(getSortResolverBean());
argumentResolvers.add(getPageableResolverBean());
ProxyingHandlerMethodArgumentResolver resolver = new ProxyingHandlerMethodArgumentResolver(conversionService, true);
resolver.setBeanFactory(context);
@@ -157,7 +156,7 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo
if (ClassUtils.isPresent("com.jayway.jsonpath.DocumentContext", context.getClassLoader())
&& ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", context.getClassLoader())) {
ObjectMapper mapper = getUniqueBean(ObjectMapper.class, context, ObjectMapper::new);
ObjectMapper mapper = context.getBeanProvider(ObjectMapper.class).getIfUnique(ObjectMapper::new);
ProjectingJackson2HttpMessageConverter converter = new ProjectingJackson2HttpMessageConverter(mapper);
converter.setBeanFactory(context);
@@ -173,6 +172,14 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo
}
}
protected SortHandlerMethodArgumentResolver getSortResolverBean() {
return context.getBean("sortResolver", SortHandlerMethodArgumentResolver.class);
}
protected PageableHandlerMethodArgumentResolver getPageableResolverBean() {
return context.getBean("pageableResolver", PageableHandlerMethodArgumentResolver.class);
}
protected void customizePageableResolver(PageableHandlerMethodArgumentResolver pageableResolver) {
pageableResolverCustomizer.ifPresent(c -> c.customize(pageableResolver));
}
@@ -188,21 +195,4 @@ public class SpringDataWebConfiguration implements WebMvcConfigurer, BeanClassLo
}
}
/**
* Returns the uniquely available bean of the given type from the given {@link ApplicationContext} or the one provided
* by the given {@link Supplier} in case the initial lookup fails.
*
* @param type must not be {@literal null}.
* @param context must not be {@literal null}.
* @param fallback must not be {@literal null}.
* @return
*/
private static <T> T getUniqueBean(Class<T> type, ApplicationContext context, Supplier<T> fallback) {
try {
return context.getBean(type);
} catch (NoSuchBeanDefinitionException o_O) {
return fallback.get();
}
}
}