Consider component names for custom implementation and fragment bean registration.
We now consider the the actual repository & fragment bean name when checking for existing bean definitions of default custom implementation beans. Previously, we used the repository interface name without considering the repository bean name. Closes #2487. Original Pull Request: #2488
This commit is contained in:
committed by
Christoph Strobl
parent
103d41f7f4
commit
70cda7949d
@@ -19,6 +19,9 @@ import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.ArgumentMatchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.beans.Introspector;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Answers;
|
||||
|
||||
@@ -36,6 +39,7 @@ import org.springframework.mock.env.MockEnvironment;
|
||||
* tests {@link CustomRepositoryImplementationDetector}
|
||||
*
|
||||
* @author Jens Schauder
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
class CustomRepositoryImplementationDetectorUnitTests {
|
||||
|
||||
@@ -48,7 +52,8 @@ class CustomRepositoryImplementationDetectorUnitTests {
|
||||
CustomRepositoryImplementationDetector detector = new CustomRepositoryImplementationDetector(environment,
|
||||
resourceLoader, configuration);
|
||||
|
||||
{
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(configuration.forRepositoryConfiguration(any(RepositoryConfiguration.class))).thenCallRealMethod();
|
||||
when(configuration.getMetadataReaderFactory()).thenReturn(metadataFactory);
|
||||
when(configuration.getBasePackages()).thenReturn(Streamable.of(this.getClass().getPackage().getName()));
|
||||
@@ -58,10 +63,10 @@ class CustomRepositoryImplementationDetectorUnitTests {
|
||||
@Test // DATACMNS-764, DATACMNS-1371
|
||||
void returnsNullWhenNoImplementationFound() {
|
||||
|
||||
var mock = mock(RepositoryConfiguration.class);
|
||||
RepositoryConfiguration<?> mock = mock(RepositoryConfiguration.class);
|
||||
when(mock.getImplementationBeanName()).thenReturn("NoImplementationRepositoryImpl");
|
||||
|
||||
var lookup = configuration
|
||||
.forRepositoryConfiguration(configFor(NoImplementationRepository.class));
|
||||
var lookup = configuration.forRepositoryConfiguration(configFor(NoImplementationRepository.class));
|
||||
|
||||
var beanDefinition = detector.detectCustomImplementation(lookup);
|
||||
|
||||
@@ -71,8 +76,7 @@ class CustomRepositoryImplementationDetectorUnitTests {
|
||||
@Test // DATACMNS-764, DATACMNS-1371
|
||||
void returnsBeanDefinitionWhenOneImplementationIsFound() {
|
||||
|
||||
var lookup = configuration
|
||||
.forRepositoryConfiguration(configFor(SingleSampleRepository.class));
|
||||
var lookup = configuration.forRepositoryConfiguration(configFor(SingleSampleRepository.class));
|
||||
|
||||
var beanDefinition = detector.detectCustomImplementation(lookup);
|
||||
|
||||
@@ -91,8 +95,7 @@ class CustomRepositoryImplementationDetectorUnitTests {
|
||||
return className.contains("$First$") ? "canonicalSampleRepositoryTestImpl" : "otherBeanName";
|
||||
});
|
||||
|
||||
var lookup = configuration
|
||||
.forRepositoryConfiguration(configFor(CanonicalSampleRepository.class));
|
||||
var lookup = configuration.forRepositoryConfiguration(configFor(CanonicalSampleRepository.class));
|
||||
|
||||
assertThat(detector.detectCustomImplementation(lookup)) //
|
||||
.hasValueSatisfying(
|
||||
@@ -113,11 +116,13 @@ class CustomRepositoryImplementationDetectorUnitTests {
|
||||
});
|
||||
}
|
||||
|
||||
private RepositoryConfiguration configFor(Class<?> type) {
|
||||
private RepositoryConfiguration<?> configFor(Class<?> type) {
|
||||
|
||||
RepositoryConfiguration<?> configuration = mock(RepositoryConfiguration.class);
|
||||
|
||||
when(configuration.getRepositoryInterface()).thenReturn(type.getSimpleName());
|
||||
when(configuration.getImplementationBeanName())
|
||||
.thenReturn(Introspector.decapitalize(type.getSimpleName()) + "TestImpl");
|
||||
when(configuration.getImplementationBasePackages())
|
||||
.thenReturn(Streamable.of(this.getClass().getPackage().getName()));
|
||||
|
||||
|
||||
@@ -18,8 +18,14 @@ package org.springframework.data.repository.config;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.beans.Introspector;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link DefaultImplementationLookupConfigurationUnitTests}.
|
||||
*
|
||||
@@ -28,12 +34,18 @@ import org.junit.jupiter.api.Test;
|
||||
*/
|
||||
class DefaultImplementationLookupConfigurationUnitTests {
|
||||
|
||||
ImplementationDetectionConfiguration idcMock = mock(ImplementationDetectionConfiguration.class);
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
when(idcMock.getImplementationPostfix()).thenReturn("Impl");
|
||||
when(idcMock.forRepositoryConfiguration(any())).thenCallRealMethod();
|
||||
when(idcMock.forFragment(any())).thenCallRealMethod();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1439
|
||||
void shouldConsiderBeanNameDecapitalization() {
|
||||
|
||||
var idcMock = mock(ImplementationDetectionConfiguration.class);
|
||||
when(idcMock.getImplementationPostfix()).thenReturn("Impl");
|
||||
|
||||
assertThat(getImplementationBeanName(idcMock, "com.acme.UDPRepository")).isEqualTo("UDPRepositoryImpl");
|
||||
assertThat(getImplementationBeanName(idcMock, "com.acme.UdpRepository")).isEqualTo("udpRepositoryImpl");
|
||||
}
|
||||
@@ -41,19 +53,20 @@ class DefaultImplementationLookupConfigurationUnitTests {
|
||||
@Test // DATACMNS-1754
|
||||
void shouldUseSimpleClassNameWhenDefiningImplementationNames() {
|
||||
|
||||
var idcMock = mock(ImplementationDetectionConfiguration.class);
|
||||
when(idcMock.getImplementationPostfix()).thenReturn("Impl");
|
||||
|
||||
var lookupConfiguration = new DefaultImplementationLookupConfiguration(idcMock,
|
||||
"com.acme.Repositories$NestedRepository");
|
||||
var lookupConfiguration = idcMock.forFragment("com.acme.Repositories$NestedRepository");
|
||||
assertThat(lookupConfiguration.getImplementationBeanName()).isEqualTo("repositories.NestedRepositoryImpl");
|
||||
assertThat(lookupConfiguration.getImplementationClassName()).isEqualTo("NestedRepositoryImpl");
|
||||
}
|
||||
|
||||
private static String getImplementationBeanName(ImplementationDetectionConfiguration idcMock, String interfaceName) {
|
||||
|
||||
var configuration = new DefaultImplementationLookupConfiguration(idcMock,
|
||||
interfaceName);
|
||||
var source = mock(RepositoryConfigurationSource.class);
|
||||
when(source.generateBeanName(any())).thenReturn(Introspector.decapitalize(ClassUtils.getShortName(interfaceName)));
|
||||
|
||||
RepositoryConfiguration<?> repoConfig = new DefaultRepositoryConfiguration<>(source,
|
||||
BeanDefinitionBuilder.rootBeanDefinition(interfaceName).getBeanDefinition(), null);
|
||||
|
||||
var configuration = idcMock.forRepositoryConfiguration(repoConfig);
|
||||
return configuration.getImplementationBeanName();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class RepositoryComponentProviderUnitTests {
|
||||
provider.setConsiderNestedRepositoryInterfaces(true);
|
||||
|
||||
var components = provider.findCandidateComponents("org.springframework.data.repository.config");
|
||||
var nestedRepositoryClassName = "org.springframework.data.repository.config.RepositoryComponentProviderUnitTests$MyNestedRepository";
|
||||
var nestedRepositoryClassName = "org.springframework.data.repository.config.RepositoryComponentProviderUnitTests$MyNestedRepositoryDefinition";
|
||||
|
||||
assertThat(components.size()).isGreaterThanOrEqualTo(1);
|
||||
assertThat(components).extracting(BeanDefinition::getBeanClassName).contains(nestedRepositoryClassName);
|
||||
@@ -91,5 +91,5 @@ class RepositoryComponentProviderUnitTests {
|
||||
assertThat(provider.getRegistry()).isEqualTo(registry);
|
||||
}
|
||||
|
||||
interface MyNestedRepository extends Repository<Person, Long> {}
|
||||
interface MyNestedRepositoryDefinition extends Repository<Person, Long> {}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,15 @@ import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.mockito.junit.jupiter.MockitoSettings;
|
||||
import org.mockito.quality.Strictness;
|
||||
|
||||
import org.springframework.aop.framework.Advised;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.ListableBeanFactory;
|
||||
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.ComponentScan.Filter;
|
||||
@@ -34,8 +35,15 @@ import org.springframework.context.annotation.FilterType;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.metrics.ApplicationStartup;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.StandardAnnotationMetadata;
|
||||
import org.springframework.data.repository.config.RepositoryConfigurationDelegate.LazyRepositoryInjectionPointResolver;
|
||||
import org.springframework.data.repository.config.annotated.MyAnnotatedRepository;
|
||||
import org.springframework.data.repository.config.annotated.MyAnnotatedRepositoryImpl;
|
||||
import org.springframework.data.repository.config.annotated.MyFragmentImpl;
|
||||
import org.springframework.data.repository.config.excluded.MyOtherRepositoryImpl;
|
||||
import org.springframework.data.repository.config.stereotype.MyStereotypeRepository;
|
||||
import org.springframework.data.repository.core.support.DummyRepositoryFactoryBean;
|
||||
import org.springframework.data.repository.sample.AddressRepository;
|
||||
import org.springframework.data.repository.sample.AddressRepositoryClient;
|
||||
import org.springframework.data.repository.sample.ProductRepository;
|
||||
@@ -44,13 +52,14 @@ import org.springframework.data.repository.sample.ProductRepository;
|
||||
* Unit tests for {@link RepositoryConfigurationDelegate}.
|
||||
*
|
||||
* @author Oliver Gierke
|
||||
* @author Mark Paluch
|
||||
* @soundtrack Richard Spaven - Tribute (Whole Other*)
|
||||
*/
|
||||
@ExtendWith(MockitoExtension.class)
|
||||
@MockitoSettings(strictness = Strictness.LENIENT)
|
||||
class RepositoryConfigurationDelegateUnitTests {
|
||||
|
||||
@Mock RepositoryConfigurationExtension extension;
|
||||
RepositoryConfigurationExtension extension = new DummyConfigurationExtension();
|
||||
|
||||
@Test // DATACMNS-892
|
||||
void registersRepositoryBeanNameAsAttribute() {
|
||||
@@ -68,8 +77,7 @@ class RepositoryConfigurationDelegateUnitTests {
|
||||
|
||||
var beanDefinition = definition.getBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE).toString())
|
||||
.endsWith("Repository");
|
||||
assertThat(beanDefinition.getAttribute(FactoryBean.OBJECT_TYPE_ATTRIBUTE).toString()).endsWith("Repository");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,25 +95,6 @@ class RepositoryConfigurationDelegateUnitTests {
|
||||
|
||||
}
|
||||
|
||||
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?> configClass) {
|
||||
|
||||
var environment = new StandardEnvironment();
|
||||
var context = new AnnotationConfigApplicationContext(configClass);
|
||||
|
||||
assertThat(context.getDefaultListableBeanFactory().getAutowireCandidateResolver())
|
||||
.isInstanceOf(LazyRepositoryInjectionPointResolver.class);
|
||||
|
||||
var client = context.getBean(AddressRepositoryClient.class);
|
||||
var repository = client.getRepository();
|
||||
|
||||
assertThat(Advised.class.isInstance(repository)).isTrue();
|
||||
|
||||
var targetSource = Advised.class.cast(repository).getTargetSource();
|
||||
assertThat(targetSource).isNotNull();
|
||||
|
||||
return context.getDefaultListableBeanFactory();
|
||||
}
|
||||
|
||||
@Test // DATACMNS-1832
|
||||
void writesRepositoryScanningMetrics() {
|
||||
|
||||
@@ -126,6 +115,103 @@ class RepositoryConfigurationDelegateUnitTests {
|
||||
Mockito.verify(startup).start("spring.data.repository.scanning");
|
||||
}
|
||||
|
||||
@Test // GH-2487
|
||||
void considersDefaultBeanNames() {
|
||||
|
||||
var environment = new StandardEnvironment();
|
||||
var context = new GenericApplicationContext();
|
||||
|
||||
RepositoryConfigurationSource configSource = new AnnotationRepositoryConfigurationSource(
|
||||
AnnotationMetadata.introspect(DefaultBeanNamesConfig.class), EnableRepositories.class, context, environment,
|
||||
context.getDefaultListableBeanFactory(), new AnnotationBeanNameGenerator());
|
||||
|
||||
var delegate = new RepositoryConfigurationDelegate(configSource, context, environment);
|
||||
|
||||
delegate.registerRepositoriesIn(context, extension);
|
||||
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("myOtherRepository")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("myOtherRepositoryImpl")).isNotNull();
|
||||
}
|
||||
|
||||
@Test // GH-2487
|
||||
void considersAnnotatedBeanNamesFromRepository() {
|
||||
|
||||
var environment = new StandardEnvironment();
|
||||
var context = new GenericApplicationContext();
|
||||
|
||||
RepositoryConfigurationSource configSource = new AnnotationRepositoryConfigurationSource(
|
||||
AnnotationMetadata.introspect(AnnotatedDerivedBeanNamesConfig.class), EnableRepositories.class, context,
|
||||
environment, context.getDefaultListableBeanFactory(), new AnnotationBeanNameGenerator());
|
||||
|
||||
var delegate = new RepositoryConfigurationDelegate(configSource, context, environment);
|
||||
|
||||
delegate.registerRepositoriesIn(context, extension);
|
||||
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fooRepository")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fooRepositoryImpl")).isNotNull();
|
||||
}
|
||||
|
||||
@Test // GH-2487
|
||||
void considersAnnotatedBeanNamesFromAtComponent() {
|
||||
|
||||
var environment = new StandardEnvironment();
|
||||
var context = new GenericApplicationContext();
|
||||
|
||||
RepositoryConfigurationSource configSource = new AnnotationRepositoryConfigurationSource(
|
||||
AnnotationMetadata.introspect(AnnotatedBeanNamesConfig.class), EnableRepositories.class, context, environment,
|
||||
context.getDefaultListableBeanFactory(), new AnnotationBeanNameGenerator());
|
||||
|
||||
var delegate = new RepositoryConfigurationDelegate(configSource, context, environment);
|
||||
|
||||
delegate.registerRepositoriesIn(context, extension);
|
||||
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("myAnnotatedRepository")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("anotherBeanName")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fragment")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fragmentFragment")).isNotNull();
|
||||
}
|
||||
|
||||
@Test // GH-2487
|
||||
void skipsRegistrationOnAlreadyRegisteredBeansUsingAtComponentNames() {
|
||||
|
||||
var environment = new StandardEnvironment();
|
||||
var context = new GenericApplicationContext();
|
||||
context.setAllowBeanDefinitionOverriding(false);
|
||||
context.registerBean("fragment", MyFragmentImpl.class);
|
||||
context.registerBean("anotherBeanName", MyAnnotatedRepositoryImpl.class);
|
||||
|
||||
RepositoryConfigurationSource configSource = new AnnotationRepositoryConfigurationSource(
|
||||
AnnotationMetadata.introspect(AnnotatedBeanNamesConfig.class), EnableRepositories.class, context, environment,
|
||||
context.getDefaultListableBeanFactory(), new AnnotationBeanNameGenerator());
|
||||
|
||||
var delegate = new RepositoryConfigurationDelegate(configSource, context, environment);
|
||||
|
||||
delegate.registerRepositoriesIn(context, extension);
|
||||
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("myAnnotatedRepository")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("anotherBeanName")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fragment")).isNotNull();
|
||||
assertThat(context.getBeanFactory().getBeanDefinition("fragmentFragment")).isNotNull();
|
||||
}
|
||||
|
||||
private static ListableBeanFactory assertLazyRepositoryBeanSetup(Class<?> configClass) {
|
||||
|
||||
var context = new AnnotationConfigApplicationContext(configClass);
|
||||
|
||||
assertThat(context.getDefaultListableBeanFactory().getAutowireCandidateResolver())
|
||||
.isInstanceOf(LazyRepositoryInjectionPointResolver.class);
|
||||
|
||||
var client = context.getBean(AddressRepositoryClient.class);
|
||||
var repository = client.getRepository();
|
||||
|
||||
assertThat(Advised.class.isInstance(repository)).isTrue();
|
||||
|
||||
var targetSource = Advised.class.cast(repository).getTargetSource();
|
||||
assertThat(targetSource).isNotNull();
|
||||
|
||||
return context.getDefaultListableBeanFactory();
|
||||
}
|
||||
|
||||
@EnableRepositories(basePackageClasses = ProductRepository.class)
|
||||
static class TestConfig {}
|
||||
|
||||
@@ -140,4 +226,28 @@ class RepositoryConfigurationDelegateUnitTests {
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = AddressRepository.class),
|
||||
bootstrapMode = BootstrapMode.DEFERRED)
|
||||
static class DeferredConfig {}
|
||||
|
||||
@EnableRepositories(basePackageClasses = MyOtherRepository.class,
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyOtherRepository.class),
|
||||
excludeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyOtherRepositoryImpl.class))
|
||||
static class DefaultBeanNamesConfig {}
|
||||
|
||||
@EnableRepositories(basePackageClasses = MyStereotypeRepository.class,
|
||||
includeFilters = @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = MyStereotypeRepository.class))
|
||||
static class AnnotatedDerivedBeanNamesConfig {}
|
||||
|
||||
@EnableRepositories(basePackageClasses = MyAnnotatedRepository.class)
|
||||
static class AnnotatedBeanNamesConfig {}
|
||||
|
||||
static class DummyConfigurationExtension extends RepositoryConfigurationExtensionSupport {
|
||||
|
||||
public String getRepositoryFactoryBeanClassName() {
|
||||
return DummyRepositoryFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getModulePrefix() {
|
||||
return "commons";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.annotated;
|
||||
|
||||
import org.springframework.data.mapping.Person;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
public interface MyAnnotatedRepository extends CrudRepository<Person, String>, MyFragment {}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.annotated;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component("anotherBeanName")
|
||||
public class MyAnnotatedRepositoryImpl {}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.annotated;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
interface MyFragment {}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.annotated;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component("fragment")
|
||||
public class MyFragmentImpl implements MyFragment {}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.stereotype;
|
||||
|
||||
import org.springframework.data.mapping.Person;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component("fooRepository")
|
||||
public interface MyStereotypeRepository extends CrudRepository<Person, String> {}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2022 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
|
||||
*
|
||||
* https://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.config.stereotype;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* @author Mark Paluch
|
||||
*/
|
||||
@Component("fooRepositoryImpl")
|
||||
public class MyStereotypeRepositoryImpl {}
|
||||
Reference in New Issue
Block a user