From 454defc63712f759bb850e17a87b559a0fff265a Mon Sep 17 00:00:00 2001 From: Oliver Gierke Date: Thu, 25 Apr 2013 11:19:19 +0200 Subject: [PATCH] DATACMNS-319 - Made Repositories less greedy in looking up beans. We now don't try to eagerly lookup the beans Repositories shall capture in the constructor anymore but leniently look them up on the first request. Update tests for classes using Repositories alongside. --- .../data/repository/support/Repositories.java | 88 +++++++++++++----- .../support/DummyRepositoryFactoryBean.java | 20 +++- .../DomainClassConverterUnitTests.java | 93 +++++-------------- ...ClassPropertyEditorRegistrarUnitTests.java | 80 ++++------------ .../support/RepositoriesIntegrationTests.java | 80 ++++++++++++++++ .../support/RepositoriesUnitTests.java | 44 ++++----- 6 files changed, 220 insertions(+), 185 deletions(-) create mode 100644 src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java diff --git a/src/main/java/org/springframework/data/repository/support/Repositories.java b/src/main/java/org/springframework/data/repository/support/Repositories.java index f82ead1ae..768d43ce3 100644 --- a/src/main/java/org/springframework/data/repository/support/Repositories.java +++ b/src/main/java/org/springframework/data/repository/support/Repositories.java @@ -1,5 +1,5 @@ /* - * Copyright 2012 the original author or authors. + * Copyright 2012-2013 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. @@ -16,13 +16,16 @@ package org.springframework.data.repository.support; import java.io.Serializable; -import java.util.Collection; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; +import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryUtils; import org.springframework.beans.factory.ListableBeanFactory; import org.springframework.data.mapping.PersistentEntity; @@ -44,13 +47,16 @@ public class Repositories implements Iterable> { static final Repositories NONE = new Repositories(); private final Map, RepositoryFactoryInformation> domainClassToBeanName = new HashMap, RepositoryFactoryInformation>(); - private final Map, CrudRepository> repositories = new HashMap, CrudRepository>(); + private final Map, String> repositories = new HashMap, String>(); + + private final BeanFactory beanFactory; + private final Set repositoryFactoryBeanNames = new HashSet(); /** * Constructor to create the {@link #NONE} instance. */ private Repositories() { - + this.beanFactory = null; } /** @@ -59,28 +65,14 @@ public class Repositories implements Iterable> { * * @param factory must not be {@literal null}. */ - @SuppressWarnings({ "rawtypes", "unchecked" }) public Repositories(ListableBeanFactory factory) { Assert.notNull(factory); + this.beanFactory = factory; - Collection providers = BeanFactoryUtils.beansOfTypeIncludingAncestors(factory, - RepositoryFactoryInformation.class).values(); - - for (RepositoryFactoryInformation info : providers) { - - RepositoryInformation information = info.getRepositoryInformation(); - Class repositoryInterface = information.getRepositoryInterface(); - - if (CrudRepository.class.isAssignableFrom(repositoryInterface)) { - Class> objectType = repositoryInterface; - CrudRepository repository = BeanFactoryUtils.beanOfTypeIncludingAncestors(factory, - objectType); - - this.domainClassToBeanName.put(information.getDomainType(), info); - this.repositories.put(info, repository); - } - } + String[] beanNamesForType = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(factory, + RepositoryFactoryInformation.class, false, false); + this.repositoryFactoryBeanNames.addAll(Arrays.asList(beanNamesForType)); } /** @@ -90,6 +82,7 @@ public class Repositories implements Iterable> { * @return */ public boolean hasRepositoryFor(Class domainClass) { + lookupRepositoryFactoryInformationFor(domainClass); return domainClassToBeanName.containsKey(domainClass); } @@ -101,7 +94,14 @@ public class Repositories implements Iterable> { */ @SuppressWarnings("unchecked") public CrudRepository getRepositoryFor(Class domainClass) { - return (CrudRepository) repositories.get(domainClassToBeanName.get(domainClass)); + + RepositoryFactoryInformation information = getRepoInfoFor(domainClass); + + if (information == null) { + return null; + } + + return (CrudRepository) beanFactory.getBean(repositories.get(information)); } /** @@ -166,7 +166,7 @@ public class Repositories implements Iterable> { } } - return null; + return lookupRepositoryFactoryInformationFor(domainClass); } /* @@ -174,6 +174,46 @@ public class Repositories implements Iterable> { * @see java.lang.Iterable#iterator() */ public Iterator> iterator() { + lookupRepositoryFactoryInformationFor(null); return domainClassToBeanName.keySet().iterator(); } + + /** + * Looks up the {@link RepositoryFactoryInformation} for a given domain type. Will inspect the {@link BeanFactory} for + * beans implementing {@link RepositoryFactoryInformation} and cache the domain class to repository bean name mappings + * for further lookups. If a {@link RepositoryFactoryInformation} for the given domain type is found we interrupt the + * lookup proces to prevent beans from being looked up early. + * + * @param domainType + * @return + */ + @SuppressWarnings("unchecked") + private RepositoryFactoryInformation lookupRepositoryFactoryInformationFor(Class domainType) { + + if (domainClassToBeanName.containsKey(domainType)) { + return domainClassToBeanName.get(domainType); + } + + for (String repositoryFactoryName : repositoryFactoryBeanNames) { + + RepositoryFactoryInformation information = beanFactory.getBean(repositoryFactoryName, + RepositoryFactoryInformation.class); + + RepositoryInformation info = information.getRepositoryInformation(); + Class repositoryInterface = info.getRepositoryInterface(); + + if (!CrudRepository.class.isAssignableFrom(repositoryInterface)) { + continue; + } + + repositories.put(information, BeanFactoryUtils.transformedBeanName(repositoryFactoryName)); + domainClassToBeanName.put(info.getDomainType(), information); + + if (info.getDomainType().equals(domainType)) { + return information; + } + } + + return null; + } } 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 5201e9df2..146cc4f02 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 the original author or authors. + * Copyright 2012-2013 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. @@ -19,6 +19,7 @@ import static org.mockito.Mockito.*; import java.io.Serializable; +import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.repository.Repository; /** @@ -27,14 +28,27 @@ import org.springframework.data.repository.Repository; public class DummyRepositoryFactoryBean, S, ID extends Serializable> extends RepositoryFactoryBeanSupport { + private T repository; + + public DummyRepositoryFactoryBean() { + setMappingContext(new SampleMappingContext()); + } + + /* (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); + } + /* * (non-Javadoc) * @see org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport#createRepositoryFactory() */ @Override protected RepositoryFactorySupport createRepositoryFactory() { - - Repository repository = mock(Repository.class); return new DummyRepositoryFactory(repository); } } 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 8ed7a56bd..159213663 100644 --- a/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassConverterUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 the original author or authors. + * Copyright 2008-2013 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. @@ -21,24 +21,24 @@ import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; 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.aop.framework.Advised; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.support.DummyEntityInformation; -import org.springframework.data.repository.core.support.RepositoryFactoryInformation; +import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean; /** * Unit test for {@link DomainClassConverter}. @@ -56,17 +56,8 @@ public class DomainClassConverterUnitTests { TypeDescriptor sourceDescriptor; TypeDescriptor targetDescriptor; - @SuppressWarnings("rawtypes") - Map providers; - - @Mock - ApplicationContext context, parent; - @Mock - UserRepository repository; @Mock DefaultConversionService service; - @Mock - RepositoryFactoryInformation provider; @Before @SuppressWarnings({ "unchecked", "rawtypes" }) @@ -76,27 +67,22 @@ public class DomainClassConverterUnitTests { RepositoryInformation repositoryInformation = new DummyRepositoryInformation(UserRepository.class); converter = new DomainClassConverter(service); - providers = new HashMap(); sourceDescriptor = TypeDescriptor.valueOf(String.class); targetDescriptor = TypeDescriptor.valueOf(User.class); - - when(provider.getEntityInformation()).thenReturn(information); - when(provider.getRepositoryInformation()).thenReturn(repositoryInformation); } @Test public void matchFailsIfNoDaoAvailable() throws Exception { - converter.setApplicationContext(context); + converter.setApplicationContext(new GenericApplicationContext()); assertMatches(false); } @Test public void matchesIfConversionInBetweenIsPossible() throws Exception { - letContextContain(context, provider); - converter.setApplicationContext(context); + converter.setApplicationContext(initContextWithRepo()); when(service.canConvert(String.class, Long.class)).thenReturn(true); @@ -106,8 +92,7 @@ public class DomainClassConverterUnitTests { @Test public void matchFailsIfNoIntermediateConversionIsPossible() throws Exception { - letContextContain(context, provider); - converter.setApplicationContext(context); + converter.setApplicationContext(initContextWithRepo()); when(service.canConvert(String.class, Long.class)).thenReturn(false); @@ -136,16 +121,18 @@ public class DomainClassConverterUnitTests { @Test public void convertsStringToUserCorrectly() throws Exception { - letContextContain(context, provider); + ApplicationContext context = initContextWithRepo(); converter.setApplicationContext(context); when(service.canConvert(String.class, Long.class)).thenReturn(true); when(service.convert(anyString(), eq(Long.class))).thenReturn(1L); - when(repository.findOne(1L)).thenReturn(USER); - Object user = converter.convert("1", sourceDescriptor, targetDescriptor); - assertThat(user, is(instanceOf(User.class))); - assertThat(user, is((Object) USER)); + converter.convert("1", sourceDescriptor, targetDescriptor); + + UserRepository bean = context.getBean(UserRepository.class); + UserRepository repo = (UserRepository) ((Advised) bean).getTargetSource().getTarget(); + + verify(repo, times(1)).findOne(1L); } /** @@ -154,54 +141,24 @@ public class DomainClassConverterUnitTests { @Test public void discoversFactoryAndRepoFromParentApplicationContext() { - letContextContain(parent, provider); - when(context.getParentBeanFactory()).thenReturn(parent); + ApplicationContext parent = initContextWithRepo(); + ApplicationContext context = new GenericApplicationContext(parent); + when(service.canConvert(String.class, Long.class)).thenReturn(true); converter.setApplicationContext(context); assertThat(converter.matches(sourceDescriptor, targetDescriptor), is(true)); } - private void letContextContain(ApplicationContext context, Object bean) { + private ApplicationContext initContextWithRepo() { - configureContextToReturnBeans(context, repository, provider); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); + builder.addPropertyValue("repositoryInterface", UserRepository.class); - Map beanMap = getBeanAsMap(bean); - when(context.getBeansOfType(argThat(is(subtypeOf(bean.getClass()))))).thenReturn(beanMap); - } + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + factory.registerBeanDefinition("provider", builder.getBeanDefinition()); - private void configureContextToReturnBeans(ApplicationContext context, UserRepository repository, - RepositoryFactoryInformation provider) { - - Map map = getBeanAsMap(repository); - when(context.getBeansOfType(UserRepository.class)).thenReturn(map); - - providers.put("provider", provider); - when(context.getBeansOfType(RepositoryFactoryInformation.class)).thenReturn(providers); - } - - private Map getBeanAsMap(T bean) { - - Map beanMap = new HashMap(); - beanMap.put(bean.getClass().getName(), bean); - return beanMap; - } - - private static TypeSafeMatcher> subtypeOf(final Class type) { - - return new TypeSafeMatcher>() { - - public void describeTo(Description arg0) { - - arg0.appendText("not a subtype of"); - } - - @Override - public boolean matchesSafely(Class arg0) { - - return arg0.isAssignableFrom(type); - } - }; + return new GenericApplicationContext(factory); } private static class User { 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 aa0caffd3..649cbb4eb 100644 --- a/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/DomainClassPropertyEditorRegistrarUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2008-2012 the original author or authors. + * Copyright 2008-2013 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. @@ -15,28 +15,23 @@ */ package org.springframework.data.repository.support; -import static org.hamcrest.Matchers.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import java.io.Serializable; -import java.util.HashMap; -import java.util.Map; -import org.hamcrest.Description; -import org.hamcrest.TypeSafeMatcher; 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.PropertyEditorRegistry; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.data.repository.CrudRepository; -import org.springframework.data.repository.core.EntityInformation; -import org.springframework.data.repository.core.RepositoryInformation; -import org.springframework.data.repository.core.support.DummyEntityInformation; -import org.springframework.data.repository.core.support.RepositoryFactoryInformation; +import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean; /** * Unit test for {@link DomainClassPropertyEditorRegistrar}. @@ -46,89 +41,48 @@ import org.springframework.data.repository.core.support.RepositoryFactoryInforma @RunWith(MockitoJUnitRunner.class) public class DomainClassPropertyEditorRegistrarUnitTests { - DomainClassPropertyEditorRegistrar registrar = new DomainClassPropertyEditorRegistrar(); - @Mock - ApplicationContext context; @Mock PropertyEditorRegistry registry; - @Mock - EntityRepository repository; - @Mock - RepositoryFactoryInformation provider; + DomainClassPropertyEditorRegistrar registrar; + ApplicationContext context; DomainClassPropertyEditor reference; @Before public void setup() { - EntityInformation entityInformation = new DummyEntityInformation(Entity.class); - RepositoryInformation repositoryInformation = new DummyRepositoryInformation(EntityRepository.class); + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); + builder.addPropertyValue("repositoryInterface", EntityRepository.class); - when(provider.getEntityInformation()).thenReturn(entityInformation); - when(provider.getRepositoryInformation()).thenReturn(repositoryInformation); + DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); + factory.registerBeanDefinition("provider", builder.getBeanDefinition()); - Map map = getBeanAsMap(repository); - when(context.getBeansOfType(EntityRepository.class)).thenReturn(map); - - reference = new DomainClassPropertyEditor(repository, entityInformation, registry); + context = new GenericApplicationContext(factory); + registrar = new DomainClassPropertyEditorRegistrar(); } @Test public void addsRepositoryForEntityIfAvailableInAppContext() throws Exception { - letContextContain(provider); registrar.setApplicationContext(context); registrar.registerCustomEditors(registry); - verify(registry).registerCustomEditor(eq(Entity.class), eq(reference)); + verify(registry).registerCustomEditor(eq(Entity.class), any(DomainClassPropertyEditor.class)); } @Test public void doesNotAddDaoAtAllIfNoDaosFound() throws Exception { - letContextContain(provider); registrar.registerCustomEditors(registry); - verify(registry, never()).registerCustomEditor(eq(Entity.class), eq(reference)); + verify(registry, never()).registerCustomEditor(eq(Entity.class), any(DomainClassPropertyEditor.class)); } - private void letContextContain(Object bean) { - - Map beanMap = getBeanAsMap(bean); - - when(context.getBeansOfType(argThat(is(subtypeOf(bean.getClass()))))).thenReturn(beanMap); - } - - private Map getBeanAsMap(T bean) { - - Map beanMap = new HashMap(); - beanMap.put(bean.toString(), bean); - return beanMap; - } - - @SuppressWarnings("serial") - private static class Entity implements Serializable { + static class Entity { } - private static interface EntityRepository extends CrudRepository { + static interface EntityRepository extends CrudRepository { } - - private static TypeSafeMatcher> subtypeOf(final Class type) { - - return new TypeSafeMatcher>() { - - public void describeTo(Description arg0) { - - arg0.appendText("not a subtype of"); - } - - @Override - public boolean matchesSafely(Class arg0) { - - return arg0.isAssignableFrom(type); - } - }; - } } diff --git a/src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java b/src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java new file mode 100644 index 000000000..8a4f2a986 --- /dev/null +++ b/src/test/java/org/springframework/data/repository/support/RepositoriesIntegrationTests.java @@ -0,0 +1,80 @@ +/* + * Copyright 2013 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.support; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.*; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.repository.CrudRepository; +import org.springframework.data.repository.Repository; +import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean; +import org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +/** + * Integration tests for {@link Repositories}. + * + * @author Oliver Gierke + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +public class RepositoriesIntegrationTests { + + @Configuration + static class Config { + + @Autowired + ApplicationContext context; + + @Bean + public Repositories repositories() { + return new Repositories(context); + } + + @Bean + public RepositoryFactoryBeanSupport, User, Long> repositoryFactory() { + + DummyRepositoryFactoryBean, User, Long> factory = new DummyRepositoryFactoryBean, User, Long>(); + factory.setRepositoryInterface(UserRepository.class); + + return factory; + } + } + + @Autowired + Repositories repositories; + + @Test + public void foo() { + assertThat(repositories, is(notNullValue())); + assertThat(repositories.hasRepositoryFor(User.class), is(true)); + } + + static class User { + + } + + interface UserRepository extends CrudRepository { + + } +} 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 5517b442c..fa6a6cd90 100644 --- a/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java +++ b/src/test/java/org/springframework/data/repository/support/RepositoriesUnitTests.java @@ -19,20 +19,20 @@ package org.springframework.data.repository.support; import static org.hamcrest.CoreMatchers.*; import static org.junit.Assert.*; -import static org.mockito.Mockito.*; import java.io.Serializable; import java.util.Collections; -import java.util.HashMap; import java.util.List; -import java.util.Map; 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.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.context.ApplicationContext; +import org.springframework.context.support.GenericApplicationContext; import org.springframework.data.mapping.PersistentEntity; import org.springframework.data.mapping.context.SampleMappingContext; import org.springframework.data.repository.CrudRepository; @@ -42,6 +42,7 @@ import org.springframework.data.repository.core.RepositoryInformation; import org.springframework.data.repository.core.RepositoryMetadata; import org.springframework.data.repository.core.support.DefaultRepositoryMetadata; import org.springframework.data.repository.core.support.DummyEntityInformation; +import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean; import org.springframework.data.repository.core.support.RepositoryFactoryInformation; import org.springframework.data.repository.query.QueryMethod; @@ -53,25 +54,24 @@ import org.springframework.data.repository.query.QueryMethod; @RunWith(MockitoJUnitRunner.class) public class RepositoriesUnitTests { - @Mock - PersonRepository personRepository; - @Mock - AddressRepository addressRepository; - @Mock ApplicationContext context; @Before - @SuppressWarnings({ "unchecked", "rawtypes" }) public void setUp() { - Map factoryInformations = getBeanAsMap(new SampleRepoFactoryInformation(AddressRepository.class), - new SampleRepoFactoryInformation(PersonRepository.class)); - Map personRepositories = getBeanAsMap(personRepository); - Map addressRepositories = getBeanAsMap(addressRepository); + DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory(); + beanFactory.registerBeanDefinition("addressRepository", getRepositoryBeanDefinition(AddressRepository.class)); + beanFactory.registerBeanDefinition("personRepository", getRepositoryBeanDefinition(PersonRepository.class)); - when(context.getBeansOfType(RepositoryFactoryInformation.class)).thenReturn(factoryInformations); - when(context.getBeansOfType(PersonRepository.class)).thenReturn(personRepositories); - when(context.getBeansOfType(AddressRepository.class)).thenReturn(addressRepositories); + context = new GenericApplicationContext(beanFactory); + } + + private AbstractBeanDefinition getRepositoryBeanDefinition(Class repositoryInterface) { + + BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(DummyRepositoryFactoryBean.class); + builder.addPropertyValue("repositoryInterface", repositoryInterface); + + return builder.getBeanDefinition(); } @Test @@ -149,14 +149,4 @@ public class RepositoriesUnitTests { return Collections.emptyList(); } } - - private static Map getBeanAsMap(T... beans) { - - Map beanMap = new HashMap(); - - for (T bean : beans) { - beanMap.put(bean.toString(), bean); - } - return beanMap; - } }