반응형
일반적으로 Spring에서 @Controller를 사용하면 클래스명과 같은 이름으로 Bean이 생성됩니다.
예를 들어 UserController의 경우 userController로 생성됩니다.
그런 이유로 아래와 같이 서로 다른 패키지에 같은 이름의 클래스가 존재한다면 에러가 발생하게 됩니다.
com.user 패키지의 RequestContoller
com.dept 패키지의 RequestController
같은 이름으로 클래스를 생성하고 싶을 경우 별도의 작업을 해줘야 합니다.
1. CustomBeanNameGenerator 생성
import java.util.Set;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RestController;
public class CustomBeanNameGenerator implements BeanNameGenerator {
// 이 클래스는 Spring이 기본적으로 사용하는 BeanNameGenerator입니다. 컨트롤러가 아닐경우 이 클래스를 사용하려고 선언하였습니다.
private final AnnotationBeanNameGenerator defaultGenerator = new AnnotationBeanNameGenerator();
@Override
public String generateBeanName(final BeanDefinition definition, final BeanDefinitionRegistry registry) {
// 파라미터의 definition에는 bean을 만드려는 Class<?> 외 metadata정보를 가지고 옵니다.
final String result;
// definition이 컨트롤러일 경우 패키지 이름을 포함한 Bean 이름을, 아닐경우 Spring 기본형식을 따릅니다.
if (isController(definition)) {
result = generateFullBeanName((AnnotatedBeanDefinition) definition);
} else {
result = this.defaultGenerator.generateBeanName(definition, registry);
}
return result;
}
private String generateFullBeanName(final AnnotatedBeanDefinition definition) {
// 패키지를 포함한 전체 이름을 반환합니다.
return definition.getMetadata().getClassName();
}
private Set<String> getAnnotationTypes(final BeanDefinition definition) {
final AnnotatedBeanDefinition annotatedDef = (AnnotatedBeanDefinition) definition;
final AnnotationMetadata metadata = annotatedDef.getMetadata();
return metadata.getAnnotationTypes();
}
private boolean isController(final BeanDefinition definition) {
if (definition instanceof AnnotatedBeanDefinition) {
// definition에 속한 모든 Annotation을 가져옵니다.
final Set<String> annotationTypes = getAnnotationTypes(definition);
// annotation 중 @Controller이거나 @RestController 일 경우 Controller로 인식합니다.
for (final String annotationType : annotationTypes) {
if (annotationType.equals(Controller.class.getName())) {
return true;
}
if (annotationType.equals(RestController.class.getName())) {
return true;
}
if (annotationType.equals(Service.class.getName())) {
return true;
}
if (annotationType.equals(Repository.class.getName())) {
return true;
}
if (annotationType.equals(Component.class.getName())) {
return true;
}
}
}
return false;
}
}
2. Spring Boot의 시작 클래스(@SpringBootApplication)에 CustomBeanNameGenerator을 적용
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import com.wowsoft.docs.config.CustomBeanNameGenerator;
@SpringBootApplication
@ComponentScan(nameGenerator = CustomBeanNameGenerator.class)
public class DocsApplication extends SpringBootServletInitializer{
public static void main(String[] args) {
new SpringApplicationBuilder(DocsApplication.class)
.run(args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
return builder.sources(DocsApplication.class);
}
}
728x90
반응형
'웹 개발' 카테고리의 다른 글
Java EE 개발자는 항상 -server 옵션을 켜 두는 것이 좋다. (0) | 2019.11.15 |
---|---|
java 동적으로 filed 값 가져오기 (0) | 2019.11.14 |
[spring boot] war를 만들때 rootAbsolutePath가 null일 경우 (0) | 2019.09.23 |
[spring security] Principal in JSP EL expression (0) | 2019.09.20 |
spring 에서 sessionValue 사용 ( session정보를 담은 class 사용 ) (0) | 2019.09.06 |