[JAVA] Passen Sie den durch Spring Component-Scan festgelegten Bean-Namen an

Bei der Entwicklung mit dem "Component-Scan" von Spring (auch standardmäßig in Boot) wird der Bean-Name automatisch zugewiesen, sodass der Name leicht abgedeckt werden kann.

SampleSpringBoot
├── SampleSpringBootApplication.java
└── controller
    ├── fuga
    │   └── HelloController.java
    └── hoge
        └── HelloController.java

In diesem Fall haben sowohl fuga.HelloController als auch hoge.HelloController den Bean-Namen ** helloController **, was bedeutet, dass sie nicht gestartet werden können, weil sie abgedeckt sind.

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [net.sinsengumi.SampleSpringBoot.SampleSpringBootApplication]; nested exception is org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'helloController' for bean class [net.sinsengumi.SampleSpringBoot.controller.hoge.HelloController] conflicts with existing, non-compatible bean definition of same name and class [net.sinsengumi.SampleSpringBoot.controller.fuga.HelloController]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:181) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:270) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122) ~[spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.4.RELEASE.jar:1.5.4.RELEASE]
	at net.sinsengumi.SampleSpringBoot.SampleSpringBootApplication.main(SampleSpringBootApplication.java:10) [classes/:na]
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_112]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_112]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_112]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_112]
	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-1.5.4.RELEASE.jar:1.5.4.RELEASE]
Caused by: org.springframework.context.annotation.ConflictingBeanDefinitionException: Annotation-specified bean name 'helloController' for bean class [net.sinsengumi.SampleSpringBoot.controller.hoge.HelloController] conflicts with existing, non-compatible bean definition of same name and class [net.sinsengumi.SampleSpringBoot.controller.fuga.HelloController]
	at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.checkCandidate(ClassPathBeanDefinitionScanner.java:345) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ClassPathBeanDefinitionScanner.doScan(ClassPathBeanDefinitionScanner.java:283) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ComponentScanAnnotationParser.parse(ComponentScanAnnotationParser.java:135) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:287) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.9.RELEASE.jar:4.3.9.RELEASE]
	... 18 common frames omitted

Wenn Sie dies vermeiden möchten, können Sie den Bean-Namen beim Definieren der Komponente festlegen.

// fuga.HelloController
@RestController("fugaHelloController")

// hoge.HelloController
@RestController("hogeHelloController")

Es ist jedoch zu ärgerlich, daher ist es eine gute Idee, alles auf einmal einzustellen und es nicht abzudecken. Dies ist mit dem ** nameGenerator ** von component-scan möglich. Wenn Sie sicherstellen möchten, dass Sie im Allgemeinen nicht leiden, können Sie an FQCN denken. Aber ich denke nicht, dass das ein Problem ist.

public class FQCNBeanNameGenerator extends AnnotationBeanNameGenerator {

    @Override
    protected String buildDefaultBeanName(BeanDefinition definition) {
        return definition.getBeanClassName();
    }
}
@SpringBootApplication
@ComponentScan(nameGenerator = FQCNBeanNameGenerator.class)
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Die Bean-Namen lauten jetzt "net.sinsengumi.SampleSpringBoot.controller.fuga.HelloController" und "net.sinsengumi.SampleSpringBoot.controller.hoge.HelloController" und werden nicht behandelt.

Spring möchte, dass dieses Verhalten die Standardeinstellung ist.

Recommended Posts

Passen Sie den durch Spring Component-Scan festgelegten Bean-Namen an
Teil 4: Passen Sie das Verhalten der von Spring Security 5 unterstützten OAuth 2.0-Anmeldung an
Wenn der Bean-Klassenname dupliziert wird
Ruft den Klassennamen und den Methodennamen des Controllers ab, der vom HandlerInterceptor von Spring Boot ausgeführt wird
Verhindern von Fehlern im Logger-Namen durch Kopieren
Der offizielle Name von Spring MVC ist Spring Web MVC
[Kotlin] Ermittelt den Argumentnamen des Konstruktors durch Reflektion
Holen Sie sich den Anime-Namen für diesen Begriff durch Scraping