diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java index e28124c3a..68f0d754c 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanDefinitionBuilder.java @@ -82,13 +82,13 @@ class RepositoryBeanDefinitionBuilder { Assert.notNull(resourceLoader, "ResourceLoader must not be null!"); String factoryBeanName = configuration.getRepositoryFactoryBeanName(); - factoryBeanName = StringUtils.hasText(factoryBeanName) ? factoryBeanName : extension - .getRepositoryFactoryClassName(); + factoryBeanName = StringUtils.hasText(factoryBeanName) ? factoryBeanName + : extension.getRepositoryFactoryClassName(); BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(factoryBeanName); builder.getRawBeanDefinition().setSource(configuration.getSource()); - builder.addPropertyValue("repositoryInterface", configuration.getRepositoryInterface()); + builder.addConstructorArgValue(configuration.getRepositoryInterface()); builder.addPropertyValue("queryLookupStrategyKey", configuration.getQueryLookupStrategyKey()); builder.addPropertyValue("lazyInit", configuration.isLazyInit()); builder.addPropertyValue("repositoryBaseClass", configuration.getRepositoryBaseClassName()); @@ -127,8 +127,8 @@ class RepositoryBeanDefinitionBuilder { return beanName; } - AbstractBeanDefinition beanDefinition = implementationDetector.detectCustomImplementation( - configuration.getImplementationClassName(), configuration.getBasePackages()); + AbstractBeanDefinition beanDefinition = implementationDetector + .detectCustomImplementation(configuration.getImplementationClassName(), configuration.getBasePackages()); if (null == beanDefinition) { return null; diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryBeanNameGenerator.java b/src/main/java/org/springframework/data/repository/config/RepositoryBeanNameGenerator.java index 667adcc20..1020be8b8 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryBeanNameGenerator.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryBeanNameGenerator.java @@ -65,7 +65,7 @@ public class RepositoryBeanNameGenerator implements BeanNameGenerator, BeanClass */ private Class getRepositoryInterfaceFrom(BeanDefinition beanDefinition) { - Object value = beanDefinition.getPropertyValues().getPropertyValue("repositoryInterface").getValue(); + Object value = beanDefinition.getConstructorArgumentValues().getArgumentValue(0, Class.class).getValue(); if (value instanceof Class) { return (Class) value; diff --git a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java index 1596b67e4..04f5850a3 100644 --- a/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java +++ b/src/main/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupport.java @@ -33,7 +33,6 @@ import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.io.ResourceLoader; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.AbstractRepositoryMetadata; -import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; import org.springframework.util.Assert; import org.springframework.util.StringUtils; @@ -50,8 +49,6 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit private static final String CLASS_LOADING_ERROR = "%s - Could not load type %s using class loader %s."; private static final String MULTI_STORE_DROPPED = "Spring Data {} - Could not safely identify store assignment for repository candidate {}."; - private static final String FACTORY_BEAN_TYPE_PREDICTING_POST_PROCESSOR = "org.springframework.data.repository.core.support.FactoryBeanTypePredictingBeanPostProcessor"; - /* * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#getModuleName() @@ -114,18 +111,8 @@ public abstract class RepositoryConfigurationExtensionSupport implements Reposit * (non-Javadoc) * @see org.springframework.data.repository.config.RepositoryConfigurationExtension#registerBeansForRoot(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.data.repository.config.RepositoryConfigurationSource) */ - public void registerBeansForRoot(BeanDefinitionRegistry registry, RepositoryConfigurationSource configurationSource) { - - String typeName = RepositoryFactoryBeanSupport.class.getName(); - - BeanDefinitionBuilder builder = BeanDefinitionBuilder - .rootBeanDefinition(FACTORY_BEAN_TYPE_PREDICTING_POST_PROCESSOR); - builder.addConstructorArgValue(typeName); - builder.addConstructorArgValue("repositoryInterface"); - - registerIfNotAlreadyRegistered(builder.getBeanDefinition(), registry, typeName.concat("_Predictor"), - configurationSource.getSource()); - } + public void registerBeansForRoot(BeanDefinitionRegistry registry, + RepositoryConfigurationSource configurationSource) {} /** * Returns the prefix of the module to be used to create the default location for Spring Data named queries. diff --git a/src/main/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingBeanPostProcessor.java b/src/main/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingBeanPostProcessor.java deleted file mode 100644 index b2afe0574..000000000 --- a/src/main/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingBeanPostProcessor.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 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 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.repository.core.support; - -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.PropertyValue; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; -import org.springframework.beans.factory.config.TypedStringValue; -import org.springframework.core.Ordered; -import org.springframework.core.PriorityOrdered; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; - -/** - * {@link InstantiationAwareBeanPostProcessorAdapter} to predict the bean type for {@link FactoryBean} implementations - * by interpreting a configured property of the {@link BeanDefinition} as type to be created eventually. - * - * @author Oliver Gierke - * @since 1.12 - * @soundtrack Ron Spielmann - Lock Me Up (Electric Tales) - */ -public class FactoryBeanTypePredictingBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter - implements BeanFactoryAware, PriorityOrdered { - - private static final Logger LOGGER = LoggerFactory.getLogger(FactoryBeanTypePredictingBeanPostProcessor.class); - - private final Map> cache = new ConcurrentHashMap>(); - private final Class factoryBeanType; - private final List properties; - private ConfigurableListableBeanFactory context; - - /** - * Creates a new {@link FactoryBeanTypePredictingBeanPostProcessor} predicting the type created by the - * {@link FactoryBean} of the given type by inspecting the {@link BeanDefinition} and considering the value for the - * given property as type to be created eventually. - * - * @param factoryBeanType must not be {@literal null}. - * @param properties must not be {@literal null} or empty. - */ - public FactoryBeanTypePredictingBeanPostProcessor(Class factoryBeanType, String... properties) { - - Assert.notNull(factoryBeanType, "FactoryBean type must not be null!"); - Assert.isTrue(FactoryBean.class.isAssignableFrom(factoryBeanType), "Given type is not a FactoryBean type!"); - Assert.notEmpty(properties, "Properties must not be empty!"); - - for (String property : properties) { - Assert.hasText(property, "Type property must not be null!"); - } - - this.factoryBeanType = factoryBeanType; - this.properties = Arrays.asList(properties); - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.BeanFactoryAware#setBeanFactory(org.springframework.beans.factory.BeanFactory) - */ - public void setBeanFactory(BeanFactory beanFactory) { - - if (beanFactory instanceof ConfigurableListableBeanFactory) { - this.context = (ConfigurableListableBeanFactory) beanFactory; - } - } - - /* - * (non-Javadoc) - * @see org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter#predictBeanType(java.lang.Class, java.lang.String) - */ - @Override - public Class predictBeanType(Class beanClass, String beanName) { - - if (null == context || !factoryBeanType.isAssignableFrom(beanClass)) { - return null; - } - - Class resolvedBeanClass = cache.get(beanName); - - if (resolvedBeanClass != null) { - return resolvedBeanClass == Void.class ? null : resolvedBeanClass; - } - - BeanDefinition definition = context.getBeanDefinition(beanName); - - try { - - for (String property : properties) { - - PropertyValue value = definition.getPropertyValues().getPropertyValue(property); - resolvedBeanClass = getClassForPropertyValue(value, beanName); - - if (Void.class.equals(resolvedBeanClass)) { - continue; - } - - return resolvedBeanClass; - } - - return null; - - } finally { - cache.put(beanName, resolvedBeanClass); - } - } - - /** - * Returns the class which is configured in the given {@link PropertyValue}. In case it is not a - * {@link TypedStringValue} or the value contained cannot be interpreted as {@link Class} it will return {@link Void}. - * - * @param propertyValue can be {@literal null}. - * @param beanName must not be {@literal null}. - * @return - */ - private Class getClassForPropertyValue(PropertyValue propertyValue, String beanName) { - - if (propertyValue == null) { - return Void.class; - } - - Object value = propertyValue.getValue(); - String className = null; - - if (value instanceof TypedStringValue) { - className = ((TypedStringValue) value).getValue(); - } else if (value instanceof String) { - className = (String) value; - } else if (value instanceof Class) { - return (Class) value; - } else if (value instanceof String[]) { - - String[] values = (String[]) value; - - if (values.length == 0) { - return Void.class; - } else { - className = values[0]; - } - - } else { - return Void.class; - } - - try { - return ClassUtils.resolveClassName(className, context.getBeanClassLoader()); - } catch (IllegalArgumentException ex) { - LOGGER.warn( - String.format("Couldn't load class %s referenced as repository interface in bean %s!", className, beanName)); - return Void.class; - } - } - - /* - * (non-Javadoc) - * @see org.springframework.core.Ordered#getOrder() - */ - public int getOrder() { - return Ordered.LOWEST_PRECEDENCE - 1; - } -} diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java index a267fccfa..aa17dd497 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupport.java @@ -24,7 +24,6 @@ import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.annotation.Required; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.ApplicationEventPublisherAware; import org.springframework.data.mapping.PersistentEntity; @@ -53,10 +52,10 @@ public abstract class RepositoryFactoryBeanSupport, implements InitializingBean, RepositoryFactoryInformation, FactoryBean, BeanClassLoaderAware, BeanFactoryAware, ApplicationEventPublisherAware { - private RepositoryFactorySupport factory; + private final Class repositoryInterface; + private RepositoryFactorySupport factory; private Key queryLookupStrategyKey; - private Class repositoryInterface; private Class repositoryBaseClass; private Object customImplementation; private NamedQueries namedQueries; @@ -72,14 +71,13 @@ public abstract class RepositoryFactoryBeanSupport, private RepositoryMetadata repositoryMetadata; /** - * Setter to inject the repository interface to implement. + * Creates a new {@link RepositoryFactoryBeanSupport} for the given repository interface. * - * @param repositoryInterface the repository interface to set + * @param repositoryInterface must not be {@literal null}. */ - @Required - public void setRepositoryInterface(Class repositoryInterface) { + protected RepositoryFactoryBeanSupport(Class repositoryInterface) { - Assert.notNull(repositoryInterface); + Assert.notNull(repositoryInterface, "Repository interface must not be null!"); this.repositoryInterface = repositoryInterface; } @@ -229,9 +227,8 @@ public abstract class RepositoryFactoryBeanSupport, * (non-Javadoc) * @see org.springframework.beans.factory.FactoryBean#getObjectType() */ - @SuppressWarnings("unchecked") public Class getObjectType() { - return (Class) (null == repositoryInterface ? Repository.class : repositoryInterface); + return repositoryInterface; } /* @@ -248,8 +245,6 @@ public abstract class RepositoryFactoryBeanSupport, */ public void afterPropertiesSet() { - Assert.notNull(repositoryInterface, "Repository interface must not be null on initialization!"); - this.factory = createRepositoryFactory(); this.factory.setQueryLookupStrategyKey(queryLookupStrategyKey); this.factory.setNamedQueries(namedQueries); diff --git a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java index 9d98d6ff4..612002656 100644 --- a/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/TransactionalRepositoryFactoryBeanSupport.java @@ -40,6 +40,15 @@ public abstract class TransactionalRepositoryFactoryBeanSupport repositoryInterface) { + super(repositoryInterface); + } + /** * Setter to configure which transaction manager to be used. We have to use the bean name explicitly as otherwise the * qualifier of the {@link org.springframework.transaction.annotation.Transactional} annotation is used. By explicitly diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryBeanNameGeneratorUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryBeanNameGeneratorUnitTests.java index 10ae062e2..d9d0a0001 100644 --- a/src/test/java/org/springframework/data/repository/config/RepositoryBeanNameGeneratorUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryBeanNameGeneratorUnitTests.java @@ -62,7 +62,7 @@ public class RepositoryBeanNameGeneratorUnitTests { private BeanDefinition getBeanDefinitionFor(Class repositoryInterface) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RepositoryFactoryBeanSupport.class); - builder.addPropertyValue("repositoryInterface", repositoryInterface.getName()); + builder.addConstructorArgValue(repositoryInterface.getName()); return builder.getBeanDefinition(); } diff --git a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java index 5bee74d04..82603609e 100644 --- a/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/config/RepositoryConfigurationExtensionSupportUnitTests.java @@ -23,12 +23,7 @@ import java.util.Collection; import java.util.Collections; import org.junit.Test; -import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.annotation.Primary; -import org.springframework.core.env.StandardEnvironment; -import org.springframework.core.io.DefaultResourceLoader; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.core.type.StandardAnnotationMetadata; import org.springframework.data.repository.Repository; import org.springframework.data.repository.core.support.RepositoryFactorySupport; @@ -65,26 +60,6 @@ public class RepositoryConfigurationExtensionSupportUnitTests { assertThat(extension.isStrictRepositoryCandidate(ExtendingInterface.class), is(true)); } - /** - * @see DATACMNS-609 - */ - @Test - public void registersRepositoryInterfaceAwareBeanPostProcessorOnlyOnceForMultipleConfigurations() { - - DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); - AnnotationMetadata annotationMetadata = new StandardAnnotationMetadata(SampleConfiguration.class, true); - - DefaultResourceLoader resourceLoader = new DefaultResourceLoader(); - StandardEnvironment environment = new StandardEnvironment(); - AnnotationRepositoryConfigurationSource configurationSource = new AnnotationRepositoryConfigurationSource( - annotationMetadata, EnableRepositories.class, resourceLoader, environment); - - extension.registerBeansForRoot(beanFactory, configurationSource); - extension.registerBeansForRoot(beanFactory, configurationSource); - - assertThat(beanFactory.getBeanDefinitionCount(), is(1)); - } - static class SampleRepositoryConfigurationExtension extends RepositoryConfigurationExtensionSupport { @Override diff --git a/src/test/java/org/springframework/data/repository/core/support/DummyRepositoryFactoryBean.java b/src/test/java/org/springframework/data/repository/core/support/DummyRepositoryFactoryBean.java index 146cc4f02..10f7fff6c 100644 --- a/src/test/java/org/springframework/data/repository/core/support/DummyRepositoryFactoryBean.java +++ b/src/test/java/org/springframework/data/repository/core/support/DummyRepositoryFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 the original author or authors. + * Copyright 2012-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. @@ -25,22 +25,17 @@ import org.springframework.data.repository.Repository; /** * @author Oliver Gierke */ -public class DummyRepositoryFactoryBean, S, ID extends Serializable> extends - RepositoryFactoryBeanSupport { +public class DummyRepositoryFactoryBean, S, ID extends Serializable> + extends RepositoryFactoryBeanSupport { private T repository; - public DummyRepositoryFactoryBean() { - setMappingContext(new SampleMappingContext()); - } + public DummyRepositoryFactoryBean(Class repositoryInterface) { + + super(repositoryInterface); - /* (non-Javadoc) - * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#setRepositoryInterface(java.lang.Class) - */ - @Override - public void setRepositoryInterface(Class repositoryInterface) { this.repository = mock(repositoryInterface); - super.setRepositoryInterface(repositoryInterface); + setMappingContext(new SampleMappingContext()); } /* diff --git a/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorIntegrationTests.java b/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorIntegrationTests.java deleted file mode 100644 index 49f852fb8..000000000 --- a/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorIntegrationTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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. - * 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.repository.core.support; - -import static org.hamcrest.CoreMatchers.*; -import static org.junit.Assert.*; - -import java.util.Arrays; - -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.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. - * - * @see SPR-10517 - * @author Oliver Gierke - */ -public class FactoryBeanTypePredictingPostProcessorIntegrationTests { - - DefaultListableBeanFactory factory; - - @Before - public void setUp() { - - factory = new DefaultListableBeanFactory(); - - // Register factory bean for repository - BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); - builder.addPropertyValue("repositoryInterface", UserRepository.class); - factory.registerBeanDefinition("repository", builder.getBeanDefinition()); - - // Register predicting BeanPostProcessor - FactoryBeanTypePredictingBeanPostProcessor processor = new FactoryBeanTypePredictingBeanPostProcessor( - RepositoryFactoryBeanSupport.class, "repositoryInterface"); - processor.setBeanFactory(factory); - factory.addBeanPostProcessor(processor); - } - - @Test - public void lookupBeforeInstantiation() { - - String[] strings = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, RepositoryFactoryInformation.class, - false, false); - assertThat(Arrays.asList(strings), hasItem("&repository")); - } - - @Test - public void lookupAfterInstantiation() { - - factory.getBean(UserRepository.class); - - String[] strings = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, RepositoryFactoryInformation.class, - false, false); - assertThat(Arrays.asList(strings), hasItem("&repository")); - } - - interface UserRepository extends Repository {} -} diff --git a/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorUnitTests.java deleted file mode 100644 index 2ee1da565..000000000 --- a/src/test/java/org/springframework/data/repository/core/support/FactoryBeanTypePredictingPostProcessorUnitTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * 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 - * 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.repository.core.support; - -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; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.springframework.beans.factory.BeanFactory; -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.jndi.JndiObjectFactoryBean; - -/** - * Unit tests for {@link RepositoryInterfaceAwareBeanPostProcessor}. - * - * @author Oliver Gierke - */ -@RunWith(MockitoJUnitRunner.class) -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"; - - FactoryBeanTypePredictingBeanPostProcessor processor; - BeanDefinition beanDefinition; - - @Mock ConfigurableListableBeanFactory beanFactory; - - @Before - public void setUp() { - - 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); - } - - @Test - public void returnsDaoInterfaceClassForFactoryBean() throws Exception { - - processor.setBeanFactory(beanFactory); - assertEquals(UserDao.class, processor.predictBeanType(FACTORY_CLASS, BEAN_NAME)); - } - - @Test - public void doesNotResolveInterfaceForNonFactoryClasses() throws Exception { - - processor.setBeanFactory(beanFactory); - assertNotTypeDetected(BeanFactory.class); - } - - @Test - public void doesNotResolveInterfaceForUnloadableClass() throws Exception { - - BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(FACTORY_CLASS) - .addPropertyValue(DAO_INTERFACE_PROPERTY, "com.acme.Foo"); - - when(beanFactory.getBeanDefinition(BEAN_NAME)).thenReturn(builder.getBeanDefinition()); - - assertNotTypeDetected(FACTORY_CLASS); - } - - @Test - public void doesNotResolveTypeForPlainBeanFactory() throws Exception { - - BeanFactory beanFactory = mock(BeanFactory.class); - processor.setBeanFactory(beanFactory); - - assertNotTypeDetected(FACTORY_CLASS); - } - - @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 interface UserDao extends Repository {} -} diff --git a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java index c06a62c5f..ffbb9af73 100644 --- a/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/RepositoryFactoryBeanSupportUnitTests.java @@ -44,10 +44,9 @@ public class RepositoryFactoryBeanSupportUnitTests { ClassLoader classLoader = mock(ClassLoader.class); - RepositoryFactoryBeanSupport factoryBean = new DummyRepositoryFactoryBean(); + RepositoryFactoryBeanSupport factoryBean = new DummyRepositoryFactoryBean(SampleRepository.class); factoryBean.setBeanClassLoader(classLoader); factoryBean.setLazyInit(true); - factoryBean.setRepositoryInterface(SampleRepository.class); factoryBean.afterPropertiesSet(); Object factory = ReflectionTestUtils.getField(factoryBean, "factory"); @@ -58,14 +57,13 @@ public class RepositoryFactoryBeanSupportUnitTests { * @see DATACMNS-432 */ @Test - @SuppressWarnings("rawtypes") + @SuppressWarnings({ "rawtypes", "unchecked" }) public void initializationFailsWithMissingRepositoryInterface() { exception.expect(IllegalArgumentException.class); exception.expectMessage("Repository interface"); - RepositoryFactoryBeanSupport factoryBean = new DummyRepositoryFactoryBean(); - factoryBean.afterPropertiesSet(); + new DummyRepositoryFactoryBean(null); } interface SampleRepository extends Repository {} diff --git a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java index 13d659968..9f7e59787 100644 --- a/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/TransactionRepositoryFactoryBeanSupportUnitTests.java @@ -88,7 +88,7 @@ public class TransactionRepositoryFactoryBeanSupportUnitTests { private final CrudRepository repository = mock(CrudRepository.class); public SampleTransactionalRepositoryFactoryBean() { - setRepositoryInterface((Class) CrudRepository.class); + super((Class) CrudRepository.class); } @Override diff --git a/src/test/java/org/springframework/data/repository/sample/SampleConfiguration.java b/src/test/java/org/springframework/data/repository/sample/SampleConfiguration.java index 3293697c3..19617f927 100644 --- a/src/test/java/org/springframework/data/repository/sample/SampleConfiguration.java +++ b/src/test/java/org/springframework/data/repository/sample/SampleConfiguration.java @@ -24,18 +24,15 @@ public class SampleConfiguration { @Bean public RepositoryFactoryBeanSupport, User, Long> userRepositoryFactory() { - DummyRepositoryFactoryBean, User, Long> factory = new DummyRepositoryFactoryBean, User, Long>(); - factory.setRepositoryInterface(UserRepository.class); - - return factory; + return new DummyRepositoryFactoryBean, User, Long>(UserRepository.class); } @Bean public RepositoryFactoryBeanSupport, Product, Long> productRepositoryFactory( ProductRepository productRepository) { - DummyRepositoryFactoryBean, Product, Long> factory = new DummyRepositoryFactoryBean, Product, Long>(); - factory.setRepositoryInterface(ProductRepository.class); + DummyRepositoryFactoryBean, Product, Long> factory = new DummyRepositoryFactoryBean, Product, Long>( + ProductRepository.class); factory.setCustomImplementation(productRepository); return factory; diff --git a/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java b/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java index f62a18902..b96525b30 100644 --- a/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java @@ -214,7 +214,7 @@ public class DomainClassConverterUnitTests { private ApplicationContext initContextWithRepo() { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); - builder.addPropertyValue("repositoryInterface", UserRepository.class); + builder.addConstructorArgValue(UserRepository.class); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); factory.registerBeanDefinition("provider", builder.getBeanDefinition()); diff --git a/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java b/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java index 3522a9035..71633d70a 100644 --- a/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java @@ -51,7 +51,7 @@ public class DomainClassPropertyEditorRegistrarUnitTests { public void setup() { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); - builder.addPropertyValue("repositoryInterface", EntityRepository.class); + builder.addConstructorArgValue(EntityRepository.class); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); factory.registerBeanDefinition("provider", builder.getBeanDefinition()); diff --git a/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java b/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java index 7b32bc57d..3aac0bbd4 100644 --- a/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java @@ -73,7 +73,7 @@ public class RepositoriesUnitTests { private AbstractBeanDefinition getRepositoryBeanDefinition(Class repositoryInterface) { BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); - builder.addPropertyValue("repositoryInterface", repositoryInterface); + builder.addConstructorArgValue(repositoryInterface); return builder.getBeanDefinition(); }