DATACMNS-821 - Improved type prediction for FactoryBean implementations.
Previously, we registered an InstantiationAwareBeanPostProcessor to predict the type to be created by RepositoryFactoryBeanSupport by inspecting a particular property value of the registered BeanDefinition. This has now been elevated to a more generic mechanism that can get a FactoryBean type configured with a set of properties to inspect for a configured type. That new infrastructure now replaces the explicit configuration for RepositoryFactoryBeanSupport with one that's set up via configuration.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
* Copyright 2013-2016 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.
|
||||
@@ -20,26 +20,22 @@ import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.junit.Assume;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.core.SpringVersion;
|
||||
import org.springframework.data.querydsl.User;
|
||||
import org.springframework.data.repository.Repository;
|
||||
|
||||
/**
|
||||
* Integration test to make sure Spring Data repository factory beans are found without the factories already
|
||||
* instantiated. Only executed for Spring version newer than 3.2.2.RELEASE.
|
||||
* instantiated.
|
||||
*
|
||||
* @see SPR-10517
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
public class RepositoryInterfaceAwareBeanPostProcessorIntegrationTests {
|
||||
|
||||
static final String LAST_ERROR_VERSION = "3.2.2.RELEASE";
|
||||
public class FactoryBeanTypePredictingPostProcessorIntegrationTests {
|
||||
|
||||
DefaultListableBeanFactory factory;
|
||||
|
||||
@@ -54,7 +50,8 @@ public class RepositoryInterfaceAwareBeanPostProcessorIntegrationTests {
|
||||
factory.registerBeanDefinition("repository", builder.getBeanDefinition());
|
||||
|
||||
// Register predicting BeanPostProcessor
|
||||
RepositoryInterfaceAwareBeanPostProcessor processor = new RepositoryInterfaceAwareBeanPostProcessor();
|
||||
FactoryBeanTypePredictingBeanPostProcessor processor = new FactoryBeanTypePredictingBeanPostProcessor(
|
||||
RepositoryFactoryBeanSupport.class, "repositoryInterface");
|
||||
processor.setBeanFactory(factory);
|
||||
factory.addBeanPostProcessor(processor);
|
||||
}
|
||||
@@ -62,8 +59,6 @@ public class RepositoryInterfaceAwareBeanPostProcessorIntegrationTests {
|
||||
@Test
|
||||
public void lookupBeforeInstantiation() {
|
||||
|
||||
Assume.assumeTrue(isFixedSpringVersion());
|
||||
|
||||
String[] strings = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, RepositoryFactoryInformation.class,
|
||||
false, false);
|
||||
assertThat(Arrays.asList(strings), hasItem("&repository"));
|
||||
@@ -72,8 +67,6 @@ public class RepositoryInterfaceAwareBeanPostProcessorIntegrationTests {
|
||||
@Test
|
||||
public void lookupAfterInstantiation() {
|
||||
|
||||
Assume.assumeTrue(isFixedSpringVersion());
|
||||
|
||||
factory.getBean(UserRepository.class);
|
||||
|
||||
String[] strings = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, RepositoryFactoryInformation.class,
|
||||
@@ -81,11 +74,5 @@ public class RepositoryInterfaceAwareBeanPostProcessorIntegrationTests {
|
||||
assertThat(Arrays.asList(strings), hasItem("&repository"));
|
||||
}
|
||||
|
||||
private static boolean isFixedSpringVersion() {
|
||||
return SpringVersion.getVersion().compareTo(LAST_ERROR_VERSION) == 1;
|
||||
}
|
||||
|
||||
interface UserRepository extends Repository<User, Long> {
|
||||
|
||||
}
|
||||
interface UserRepository extends Repository<User, Long> {}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2008-2010 the original author or authors.
|
||||
* Copyright 2008-2016 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
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package org.springframework.data.repository.core.support;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
@@ -29,8 +31,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.data.repository.Repository;
|
||||
import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport;
|
||||
import org.springframework.data.repository.core.support.RepositoryInterfaceAwareBeanPostProcessor;
|
||||
import org.springframework.jndi.JndiObjectFactoryBean;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link RepositoryInterfaceAwareBeanPostProcessor}.
|
||||
@@ -38,29 +39,26 @@ import org.springframework.data.repository.core.support.RepositoryInterfaceAware
|
||||
* @author Oliver Gierke
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class RepositoryInterfaceAwareBeanPostProcessorUnitTests {
|
||||
public class FactoryBeanTypePredictingPostProcessorUnitTests {
|
||||
|
||||
private static final Class<?> FACTORY_CLASS = RepositoryFactoryBeanSupport.class;
|
||||
private static final String BEAN_NAME = "foo";
|
||||
private static final String DAO_INTERFACE_PROPERTY = "repositoryInterface";
|
||||
|
||||
private RepositoryInterfaceAwareBeanPostProcessor processor;
|
||||
FactoryBeanTypePredictingBeanPostProcessor processor;
|
||||
BeanDefinition beanDefinition;
|
||||
|
||||
@Mock
|
||||
private ConfigurableListableBeanFactory beanFactory;
|
||||
private BeanDefinition beanDefinition;
|
||||
@Mock ConfigurableListableBeanFactory beanFactory;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FACTORY_CLASS).addPropertyValue(
|
||||
DAO_INTERFACE_PROPERTY, UserDao.class);
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FACTORY_CLASS)
|
||||
.addPropertyValue(DAO_INTERFACE_PROPERTY, UserDao.class);
|
||||
this.beanDefinition = builder.getBeanDefinition();
|
||||
this.processor = new FactoryBeanTypePredictingBeanPostProcessor(FACTORY_CLASS, "repositoryInterface");
|
||||
|
||||
when(beanFactory.getBeanDefinition(BEAN_NAME)).thenReturn(beanDefinition);
|
||||
|
||||
processor = new RepositoryInterfaceAwareBeanPostProcessor();
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -80,8 +78,8 @@ public class RepositoryInterfaceAwareBeanPostProcessorUnitTests {
|
||||
@Test
|
||||
public void doesNotResolveInterfaceForUnloadableClass() throws Exception {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FACTORY_CLASS).addPropertyValue(
|
||||
DAO_INTERFACE_PROPERTY, "com.acme.Foo");
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FACTORY_CLASS)
|
||||
.addPropertyValue(DAO_INTERFACE_PROPERTY, "com.acme.Foo");
|
||||
|
||||
when(beanFactory.getBeanDefinition(BEAN_NAME)).thenReturn(builder.getBeanDefinition());
|
||||
|
||||
@@ -97,16 +95,36 @@ public class RepositoryInterfaceAwareBeanPostProcessorUnitTests {
|
||||
assertNotTypeDetected(FACTORY_CLASS);
|
||||
}
|
||||
|
||||
private void assertNotTypeDetected(Class<?> beanClass) {
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void rejectsNonFactoryBeanType() {
|
||||
new FactoryBeanTypePredictingBeanPostProcessor(Object.class, "property");
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DATACMNS-821
|
||||
*/
|
||||
@Test
|
||||
public void usesFirstValueIfPropertyIsOfArrayType() {
|
||||
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(JndiObjectFactoryBean.class);
|
||||
builder.addPropertyValue("proxyInterfaces",
|
||||
new String[] { Serializable.class.getName(), Iterable.class.getName() });
|
||||
|
||||
when(beanFactory.getBeanDefinition(BEAN_NAME)).thenReturn(builder.getBeanDefinition());
|
||||
|
||||
processor = new FactoryBeanTypePredictingBeanPostProcessor(JndiObjectFactoryBean.class, "proxyInterface",
|
||||
"proxyInterfaces");
|
||||
processor.setBeanFactory(beanFactory);
|
||||
|
||||
assertThat(processor.predictBeanType(JndiObjectFactoryBean.class, BEAN_NAME),
|
||||
is(typeCompatibleWith(Serializable.class)));
|
||||
}
|
||||
|
||||
private void assertNotTypeDetected(Class<?> beanClass) {
|
||||
assertThat(processor.predictBeanType(beanClass, BEAN_NAME), is(nullValue()));
|
||||
}
|
||||
|
||||
private class User {
|
||||
private class User {}
|
||||
|
||||
}
|
||||
|
||||
private interface UserDao extends Repository<User, Long> {
|
||||
|
||||
}
|
||||
private interface UserDao extends Repository<User, Long> {}
|
||||
}
|
||||
Reference in New Issue
Block a user