https://www.maeil-mail.kr/question/72
요약: @SpringBootApplication
은 spring project가 처음 로드될 때 실행되며, 이 내부에는 @ComponentScan
을 내포하고 있음. @ComponentScan
을 통해서 @Component
가 붙은 클래스를 찾아서 스프링 빈에 등록하는데, @Controller
,@Service
, @Repository
는 내부에 @Component
가 붙어 있으므로, 컴포넌트 스캔에 의해서 스프링 빈에 등록되며, 각자의 기능에 따라서 @Component
와는 다른 기능을 수행함
@Repository는 @Component의 기능을 수행함과 동시에, 다음과 같은 기능을 수행한다.
이 기능은 다음과 같은 PersistenceExceptionTranslationPostProcessor
라는 빈 후처리기에서 구현된다.
@AutoConfiguration
@ConditionalOnClass({PersistenceExceptionTranslationPostProcessor.class})
public class PersistenceExceptionTranslationAutoConfiguration {
public PersistenceExceptionTranslationAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnProperty(
prefix = "spring.dao.exceptiontranslation",
name = {"enabled"},
matchIfMissing = true
)
public static PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(Environment environment) {
PersistenceExceptionTranslationPostProcessor postProcessor = new PersistenceExceptionTranslationPostProcessor();
boolean proxyTargetClass = (Boolean)environment.getProperty("spring.aop.proxy-target-class", Boolean.class, Boolean.TRUE);
postProcessor.setProxyTargetClass(proxyTargetClass);
return postProcessor;
}
}
Mysql
,Oracle
,Firebase
에서 나오는 각 Exception은 다를 수 밖에 없음DataAccessException
로 변환하여 특정벤더에 종속적이지 않는 코드를 반환함SqlException
이 아닌 checkedException
을 던져서 유연성 있는 코드를 짤 수 있다.컨트롤러는 기본적으로 디스패처 서블릿에서 받은 url을 통해서 동작을 수행한다. 이를 수행하기 위해서는 컨트롤러는 핸들러로 등록이 되어서 핸들러 어뎁터, 핸들러 이 두가지의 매핑 과정을 수행해야한다.
그런데 @Component
만 수행시 핸들러로 등록이 되지않아서 컨트롤러의 작업을 수행할 수 없다.
public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMapping
implements MatchableHandlerMapping, EmbeddedValueResolverAware {
...
@Override
protected boolean isHandler(Class<?> beanType) {
return AnnotatedElementUtils.hasAnnotation(beanType, Controller.class); // 컨트롤러 애너테이션인지 확인
}
...
}
따라서 컨트롤러를 등록하고 싶은 클래스에는 반드시 @Controller를 등록해야한다.
보다 중요한 것은 개발자 이 클래스가 서비스단의 코드인지, 리포지토리 단의 코드인지, 컨트롤러단의 코드인지를 바로 식별할 수 있다는 것이 내가 느끼기에는 큰 장점이다.